【问题标题】:Difference between Reflection and Late Binding in java with real time examplesjava中反射和后期绑定的区别与实时示例
【发布时间】:2012-01-24 09:41:04
【问题描述】:

在学习 Java 教程时,反射和后期绑定让我感到困惑。在一些教程中,他们写道它们都是相同的,并且反射和后期绑定之间没有任何区别。但是其他教程说有区别。

我很困惑,所以有人可以解释一下 Java 中的反射和后期绑定是什么,如果可能的话,请给我一些现实世界的例子。

谢谢..

【问题讨论】:

    标签: java reflection late-binding


    【解决方案1】:

    Java 使用后期绑定来支持多态性;这意味着应该使用许多方法中的哪一个的决定被推迟到运行时。

    以 N 个类实现接口的抽象方法(或抽象类,fwiw)为例。

    public interface IMyInterface {
    
        public void doSomething();    
    }
    
    public class MyClassA implements IMyInterface {
    
        public void doSomething(){ ... }
    }
    
    public class MyClassB implements IMyInterface {
    
        public void doSomething(){ ... }
    }
    
    public class Caller {
    
        public void doCall(IMyInterface i){
            // which implementation of doSomething is called?
            // it depends on the type of i: this is late binding
            i.doSomething(); 
        }
    }
    

    反射用于描述能够检查其他代码的代码,即。知道类中哪些方法或属性可用,按名称调用方法(或加载类),以及在运行时做很多非常有趣的事情。

    这里有一个很好的反射解释:What is reflection and why is it useful?

    【讨论】:

      【解决方案2】:

      后期绑定(也称为动态调度)不需要反射——它仍然需要知道哪个成员在编译时动态绑定(即成员的签名在编译时是已知的),即使绑定到被覆盖的成员是在运行时发生的。

      在进行反射时,您甚至不知道您正在使用 哪个 成员(在编译时甚至不知道 name,更不用说签名了) -- 一切都发生在运行时,所以速度要慢很多。

      【讨论】:

      • 不确定性能是否真的是比较语言的不同特性时考虑的最佳维度,它们旨在解决不同的问题......
      【解决方案3】:

      现实世界的例子:

      如果您使用 jdesktop 0.8 构建项目,但附带 jdesktop 0.9,您的代码仍将使用 0.9 功能,因为它利用后期绑定,即您的代码调用的代码是由类加载器,与编译它的版本无关。 (这与链接器相反,链接器将被调用代码的编译时版本嵌入到应用程序中。)

      对于反射,假设您尝试以 Java 1.5 和 1.6 为目标,但如果 1.6 中的选项卡组件可用,那么您将通过在 JTabbedPane 类上使用反射来检查它们是否存在以查找 @ 987654321@ 方法。在这种情况下,您正在构建 Java 1.5,它根本没有这些功能,因此您不能直接调用它们,否则编译将失败。但是,如果在最终用户的系统上您发现自己在运行 1.6(此处使用后期绑定),您可以使用反射来调用 1.5 中不存在的方法。

      它们是相关的;反射的许多用途都依赖于后期绑定才能发挥作用,但它们是语言及其实现的根本不同方面。

      【讨论】:

        【解决方案4】:

        “后期绑定”解决的一个重要问题是多态性,即沿着类层次结构调用正确的覆盖方法是在运行时确定的,而不是在编译期间确定的。反射是在运行时收集和操作有关对象的信息的功能。例如。您可以在运行时使用对象的“类”属性获取对象的所有属性或方法名称,并调用这些方法或操作其属性。

        在下面的代码中,您可以通过反射的方式动态创建一个新对象(查看如何使用类检索和访问构造函数,而不是简单地使用像 object obj = new MyClass("MyInstance") 之类的东西)。以类似的方式,可以访问其他构造函数形式、方法和属性。有关 java 中反射的更多信息,请访问:http://java.sun.com/developer/technicalArticles/ALT/Reflection/

        ... in some method of some class ... Class c = getClass(); Constructor ctor = c.getConstructor( String.class ); Object obj = ctor.newInstance( "MyInstance" );

        【讨论】:

          【解决方案5】:

          我不得不不同意这里的大多数回复-

          每个人都将 Java 在运行时将方法实现归零的做法称为后期绑定,但在我看来,将术语后期绑定用于 Java 所做的事情是不正确的。

          后期绑定意味着在编译时绝对不会检查方法调用,如果方法不存在也不会出现编译错误。

          但是,如果方法在限定方法调用的类型的类型层次结构中的某处不存在,Java 将引发编译错误(在此处描述行为时有点近似)。这不是纯粹的传统后期绑定。 Java 在正常的非私有非最终非静态方法调用中所做的最好称为动态调度。
          但是,如果我们在 Java 中使用反射,那么 Java 会执行纯后期绑定,因为编译器根本无法验证被调用的方法是否存在。 这是一个例子:

          class A
          {
              public void foo()
              {
                  System.out.println("Foo from A");
              }
          }
          
          class B extends A
          {
              public void foo()
              {
                  System.out.println("Foo from B");
              }
          }
          public class C
          {
             public static void main(String [] args)
              {
                   A a=new A();
                   B b=new B();
                   A ref=null;
                   Class ref1 = null;
                   ref1 = b.getClass();
                   ref.foo1();//will not compile because Java in this normal method
                   //call does some compile time checks for method and method 
                   //signature existence. NOT late binding in its pure form.
                   try {
                      ref1.getMethod("foo1").invoke(null); //will throw a 
                      //NoSuchMethodException at runtime, but compiles perfectly even 
                      //though foo1 does not exist. This is pure late binding.
                  } catch (Exception e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  } 
                 }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-09
            • 1970-01-01
            • 1970-01-01
            • 2018-10-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-02
            相关资源
            最近更新 更多