Java 动态绑定(bind)与静态绑定(bind)

标签 java dynamic methods binding static

我有一个关于动态与静态的简单问题。因此,根据我的阅读,静态绑定(bind)适用于私有(private)、最终、重载、静态方法,并且它依赖于引用的类型。例如,动态方法不是私有(private)的、最终的、重载的,并且依赖于对象的类型。

如果您执行类似 Human myobj = new Boy(); 的操作,哪个是引用类型,哪个是对象类型?

最佳答案

您关于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 的文档:

Invoke a class (static) method

来自 invokespecial 的文档:

Invoke instance method; special handling for superclass, private, and instance initialization method invocations

来自 invokevirtual 的文档:

Invoke instance method; dispatch based on class

“Dispatch based”表示动态绑定(bind),另外两个是静态绑定(bind)。

还有两个调用指令:

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

关于Java 动态绑定(bind)与静态绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33574371/

相关文章:

java - Java 中私有(private)静态嵌套类中的访问修饰符

html - 通过 html 设置 css 值?

postgresql - 如何在plpgsql中语法动态插入

java - 如何将背景颜色更改为 RecycleView 中的特定查看器项目?

java - 不支持发布版本 1.8

c++ - 我试图了解内存分配的工作原理以及发生的时间

java - 是否可以通过类方法访问实例方法和变量

python - 如何将一个字符串的前两个字母与第二个字符串的前两个字母交换?

java - 如何按降序对字符串编号进行排序?

java - Selenium UnreachableBrowserException - Java