2015-11-06 85 views
0

我有一个关于动态与静态的简单问题。所以从我读过的内容来看,静态绑定是针对私有的,最终的,重载的静态方法,它依赖于引用的类型。动态是例如方法不是私有的,最终的,重载的并且依赖于对象的类型。Java动态与静态绑定

如果你这样做Human myobj = new Boy();,这是引用类型和它是对象的类型?

+2

因此......您认识到静态和动态绑定适用于*方法*,但随后询问有关对象和引用的内容? –

+0

我不是专家,但我相信你的例子也是静态的。所有信息都可以在编译时使用,所以编译器应该能够执行所有必要的检查。引用的类型是“人”,对象的类型是“男孩”,就像它在锡上说的一样。 – markspace

回答

1

静态的Java绑定,而动态绑定运行期间发生,所以你的类型是人与物体的类型(如果你做例如的instanceof)将男孩在编译时有发生。

2

你的说法是不正确有关final和超载。不知道你读到哪里。

使用Java 8(1.8.0_51)编译以下代码。

public class Test { 
    public static void main(String[] args) { 
     Test x = new Test(); 
     x.a(); 
     x.b(); 
     x.c(); 
     x.d(1); 
     x.d(1L); 
     x.d(1d); 
     x.d(null); 
    } 
    private  void a() {} 
    public final void b() {} 
    public static void c() {} 
    private  void d(int x) {} 
    public final void d(long x) {} 
    public static void d(double x) {} 
    public  void d(String x) {} 
} 

注意:使用实例变量调用静态方法是不好的形式。应该使用类名完成,因此显式静态。代码使用实例变量仅用于说明目的。

反编译的字节码显示:

0: new   #1     // class test/Test 
    3: dup 
    4: invokespecial #19     // Method "<init>":()V 
    7: astore_1 
    8: aload_1 
    9: invokespecial #20     // Method a:()V 
    12: aload_1 
    13: invokevirtual #23     // Method b:()V 
    16: invokestatic #26     // Method c:()V 
    19: aload_1 
    20: iconst_1 
    21: invokespecial #29     // Method d:(I)V 
    24: aload_1 
    25: lconst_1 
    26: invokevirtual #33     // Method d:(J)V 
    29: dconst_1 
    30: invokestatic #36     // Method d:(D)V 
    33: aload_1 
    34: aconst_null 
    35: invokevirtual #39     // Method d:(Ljava/lang/String;)V 
    38: return 

private方法a()d(int)专门调用。
static方法c()d(double)静态调用。
其余的方法b()d(long)d(String)几乎被调用。

正如你所看到的,final和超载不影响结果。

invokestatic文档:

调用一个类别(静态)方法

invokespecial文档:

调用实例方法;特殊处理的超类,私人,和实例的初始化方法调用

invokevirtual文件:

调用例如方法; 调度基于上类

“调度基于”是指动态绑定,其他两个是静态绑定。

还有两个调用指令:

  • invokeinterface:像invokevirtual但接口的参考,而不是类引用。
  • invokedynamic:主要用于动态(脚本化)语言,例如Groovy和“通过执行invokevirtual指令来调用”。