java 中反射和后期绑定的区别及实时示例

发布于 2024-12-28 20:56:09 字数 159 浏览 2 评论 0原文

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

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

谢谢..

While studying Java tutorials, Reflection and Late Binding have confused me. In some tutorials, they have written that they are both the same, and that there isn't any difference between Reflection and Late Binding. But other tutorials say that there is a difference.

I am confused, so can someone please explain what Reflection and Late Binding are in Java, and if posible, please give me some real world examples of both.

Thanks..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

终弃我 2025-01-04 20:56:09

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(); 
    }
}

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

关于反射的一个非常好的解释是:什么是反射以及为什么它是反射有用吗?

Java uses late-binding to support polymorphism; which means the decision of which of the many methods should be used is deferred until runtime.

Take the case of N classes implementing an abstract method of an interface (or an abstract class, 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(); 
    }
}

Reflection is used instead to describe code which is able to inspect other code, ie. to know which methods or attributes are available in a class, to call a method (or load a class) by name, and doing a lot of very interesting things at runtime.

A very nice explaination of reflection is here: What is reflection and why is it useful?

心奴独伤 2025-01-04 20:56:09

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

在进行反射时,您甚至不知道您正在使用哪个成员(甚至在编译时都不知道名称,更不用说签名了)-- < em>所有事情都发生在运行时,所以速度慢很多。

Late binding (also known as dynamic dispatch) does not need reflection -- it still needs to know which member to dynamically bind to at compile-time (i.e. the signature of the member is known at compile-time), even though the binding to overridden members happens at run-time.

When doing reflection, you don't even know which member you're using (not even the name is known at compile-time, let alone the signature) -- everything happens at run-time, so it's a lot slower.

白鸥掠海 2025-01-04 20:56:09

现实世界的示例:

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

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

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

Real world examples:

If you build your project with jdesktop 0.8, but ship with jdesktop 0.9, your code will still use the 0.9 features, because it takes advantage of late binding, i.e. the code that your code calls is the version that is loaded by the class loader, irrespective of the version that it was compiled against. (This is as opposed to linkers, which embed the compile-time version of the called code into the application.)

For reflection, let's say you are trying to target Java 1.5 and 1.6, but want to use tab components in 1.6 if they are available, then you'll check for their presence by using reflection on the JTabbedPane class to find the setTabComponentAt method. In this case you're building against Java 1.5, which doesn't have those features at all, so you can't call them directly or the compile will fail. However if on the end-user's system you find yourself running against 1.6 (late binding comes into play here) you can use reflection to call methods that didn't exist in 1.5.

They are related; many uses of reflection rely on late binding to be useful, but they are fundamentally different aspects of the language and its implementation.

自由范儿 2025-01-04 20:56:09

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

在下面的代码中,您可以通过反射的方式动态创建一个新对象(了解如何使用 Class 检索和访问构造函数,而不是简单地使用 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" );

One important issue which is addressed by "Late Binding" is the polymorphism, i.e. that the call of the proper overriden method along your class hierachy is determined during the run-time, not during compilation. Reflection is the feature to gather and manipulate information about your objects during run-time. E.g. you can get all attributes or method names of an object using its 'Class' attribute during the runtime and call those methods or manipulate its attributes.

In following code you can dynamically create a new object by the means of reflection (see how the constructor is retrieved and accessed using a Class, instead of using simply something like object obj = new MyClass( "MyInstance" ) ). In a similar way it is possible to access other constructor forms, methods and attributes. For more information about reflection in java visit: 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" );

小猫一只 2025-01-04 20:56:09

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

每个人都将 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();
        } 
       }
}

I have to disagree with most of the responses here -

Everyone calls what Java does in terms of zeroing in on a method implementation at runtime as late binding, but in my opinion its not correct to use the term late binding for what java does.

Late binding implies absolutely no checks on a method call at compile time and no compilation errors if the method does not exist.

Java however will throw a compile error if the method does not exist somewhere in the type hierarchy of the type qualifying the method call (being somewhat approximate when describing the behavior here). This is not pure traditional late binding.
What Java does in a normal non private non final non static method call would be better termed as dynamic dispatch.
However if we use reflection in Java, then Java does perform pure late binding as the compiler simply cannot verify if the called method exists or not.
Here is an example:

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();
        } 
       }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文