【问题标题】:What is a callback method in Java? (Term seems to be used loosely)Java中的回调方法是什么? (术语似乎使用松散)
【发布时间】:2013-10-16 13:57:08
【问题描述】:

我不明白什么是回调方法,而且我听说人们非常松散地使用该术语。在 Java 世界中,什么是回调方法?如果有人可以提供一些 Java 回调方法的示例代码并进行解释,那将对我的 Java 学习之旅有很大帮助。

【问题讨论】:

    标签: java spring-mvc callback


    【解决方案1】:

    回调是一段代码,您将其作为参数传递给其他代码,以便它执行它。由于 Java 还不支持函数指针,因此它们被实现为 Command 对象。类似的东西

    public class Test {
        public static void main(String[] args) throws  Exception {
            new Test().doWork(new Callback() { // implementing class            
                @Override
                public void call() {
                    System.out.println("callback called");
                }
            });
        }
    
        public void doWork(Callback callback) {
            System.out.println("doing work");
            callback.call();
        }
    
        public interface Callback {
            void call();
        }
    }
    

    回调通常会持有对某些状态的引用以使其真正有用。

    通过使回调实现对您的代码具有所有依赖关系,您可以在您的代码和执行回调的代码之间获得间接性。

    【讨论】:

    • 这是一个很好的例子,我想补充一下:回调方法可以是任何类中的任何方法;对该类实例的引用保存在其他某个类中,并且当该其他类中发生某些事件时,它会从第一个类中调用该方法。使其成为回调与任何其他方法调用不同的唯一一点是传递对对象的引用以使该对象稍后调用其方法的想法,通常是在某些事件上。
    • 对不起,我是 java 新手。这可以在没有匿名类的情况下完成吗?它必须是回调接口吗?如果有办法不使用回调接口,你能提供一个不使用回调接口的不同示例吗?
    • @ImtiazAhmad 不,匿名类是为了使示例更短。你可以创建一个public class MyCallbackImpl implements Callback
    • @ImtiazAhmad 如果没有回调,则需要在doWork() 方法中直接调用匿名类中的代码。
    • 如何在doWork()方法中直接调用?
    【解决方案2】:

    java 中的回调方法是在事件(称为E)发生时调用的方法。通常,您可以通过将某个接口的实现传递给负责触发事件E 的系统来实现它(参见示例1)。

    同样在更大更复杂的系统中,您可以简单地注释一个方法,系统将识别所有注释的方法,并在事件发生时调用它们(参见示例 2)。当然,系统会定义该方法应该接收哪些参数以及其他约束。

    示例 1:

    public interface Callback {
        //parameters can be of any types, depending on the event defined
        void callbackMethod(String aParameter);
    }
    
    
    public class CallbackImpl implements Callback {
        void callbackMethod(String aParameter) {
         //here you do your logic with the received paratemers
         //System.out.println("Parameter received: " + aParameter);
    
        }
    }
    
    //.... and then somewhere you have to tell the system to add the callback method
    //e.g. systemInstance.addCallback(new CallbackImpl());
    

    示例 2:

    //by annotating a method with this annotation, the system will know which method it should call. 
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface CallbackAnnotation {}
    
    
    public class AClass {
    
        @CallbackAnnotation
        void callbackMethod(String aParameter) {
         //here you do your logic with the received paratemers
         //System.out.println("Parameter received: " + aParameter);
    
        }
    }
    
    //.... and then somewhere you have to tell the system to add the callback class
    //and the system will create an instance of the callback class
    //e.g. systemInstance.addCallbackClass(AClass.class);
    

    【讨论】:

      【解决方案3】:

      通过使用回调机制,我们将获得我们自己的方法实现只回调。或单击事件时的特定实现。 它主要用于java中的EventHandlers中。

      
      package com.callbackExample;
      
      public abstract interface SomeEventHandler {
          public abstract void hadleClick();//by default abstract
      
      }
      
      package com.callbackExample;
      
      public class SomeEventImplementation implements SomeEventHandler {
      
          @Override
          public void hadleClick() {
              System.out.println("Click Handler : clicked");
          }
      
      }
      
      package com.callbackExample;
      
      public class Button {
          public void onClick(SomeEventHandler clickEventHandler) {
              clickEventHandler.hadleClick();
          }
      
      }
      package com.callbackExample;
      
      public class Test {
          public static void main(String[] args) {
              Button button=new Button();
              SomeEventImplementation someEventImplementation=new SomeEventImplementation();
              button.onClick(someEventImplementation);
              
              Button button2=new Button();
              button2.onClick(new SomeEventHandler() {
                  
                  @Override
                  public void hadleClick() {
                      System.out.println("button2 : my own implementation..");
                  }
              });
          }
      
      }
      
      -------------------------------------------
      OUTPUT  : Click Handler : clicked
                button2 : my own implementation..
      -------------------------------------------
      

      【讨论】:

        【解决方案4】:

        简单来说,回调机制是指以另一个函数作为参数调用一个函数。在 C、C++ 等语言中,这是通过将函数指针作为参数传递来完成的,但 java 没有指针的概念。解决方法是接口。我们传递对接口的引用而不是指针。看完下面的代码,你的理解就会一清二楚。 为了展示真实世界的应用程序,想象一下购买鼠标和鼠标垫。鼠标垫价格是固定的,但鼠标价格因品牌而异。

        interface mouse
        {
            double mousePrice();
        }
        class BrandA implements mouse
        {
            public double mousePrice()          //note that public access modifier is needed as all methods of interface are public are by default and when you override them
            //you cannot use any access modifier more restrictive
            {
                return 100;
            }
        
        }
        
        class BrandB implements mouse
        {
            public double mousePrice()
            {
                return 200;
            }
        
        }
        
        class Simple
        {
            static void total(mouse t)
            {
                double mousepad = 20;
                double mousep = t.mousePrice();
                System.out.println(mousepad + mousep);
            }
            public static void main(String args[])
            {
                mouse ob = new BrandA();        //upcasting. 
                total(ob);
            }
        }
        

        【讨论】:

          【解决方案5】:

          @Sotirios Delimanolis 的回答很好,但我想给出一个清晰的例子,以某种方式解释回调的侦听器如何工作 - android 库大量采用以下方法。

          class RemoteClass {
          
              private OnChangeListener mOnChangeListener;
          
              void makeSomeChanges() {
                  /*
                  .. do something here and call callback
                  */
                  mOnChangeListener.onChanged(this, 1);
              }
          
              public void setOnChangeListener(OnChangeListener listener) {
                  mOnChangeListener = listener;
              }
          
              public interface OnChangeListener {
                  public void onChanged(RemoteClass remoteClass, int test);
              }
          }
          

          有一个类构建了我的某人,它的名称为 RemoteClass,并告诉您的类通过将 OnChangeListener 接口的实现传递给 setOnChangeListener 方法来引用回调。

          class Test {
          
              public static void main(String[] args) {    
                  RemoteClass obj = new RemoteClass();
                  obj.setOnChangeListener(demoChanged);
                  obj.makeSomeChanges();
              }
          
              private static RemoteClass.OnChangeListener demoChanged = new RemoteClass.OnChangeListener() {
                  @Override
                  public void onChanged(RemoteClass remoteClass, int incoming) {
                      switch (incoming) {
                          case 1:
                              System.out.println("I will take appropriate action!");
                              break;
                          default:
                              break;
                      }
                  }
              };
          }
          

          现在你的类已经完成了它的任务,RemoteClass 完成了它的工作,并在必要时调用makeSomeChanges 导致使用mOnChangeListener 引用执行onChanged 方法。

          【讨论】:

            猜你喜欢
            • 2018-10-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-14
            • 2011-10-26
            相关资源
            最近更新 更多