我有一个关于动态与静态的简单问题。所以从我读过的内容来看,静态绑定是针对私有的,最终的,重载的静态方法,它依赖于引用的类型。动态是例如方法不是私有的,最终的,重载的并且依赖于对象的类型。Java动态与静态绑定
如果你这样做Human myobj = new Boy();
,这是引用类型和它是对象的类型?
我有一个关于动态与静态的简单问题。所以从我读过的内容来看,静态绑定是针对私有的,最终的,重载的静态方法,它依赖于引用的类型。动态是例如方法不是私有的,最终的,重载的并且依赖于对象的类型。Java动态与静态绑定
如果你这样做Human myobj = new Boy();
,这是引用类型和它是对象的类型?
静态的Java绑定,而动态绑定运行期间发生,所以你的类型是人与物体的类型(如果你做例如的instanceof)将男孩在编译时有发生。
你的说法是不正确有关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
指令来调用”。
因此......您认识到静态和动态绑定适用于*方法*,但随后询问有关对象和引用的内容? –
我不是专家,但我相信你的例子也是静态的。所有信息都可以在编译时使用,所以编译器应该能够执行所有必要的检查。引用的类型是“人”,对象的类型是“男孩”,就像它在锡上说的一样。 – markspace