Java null 对象访问 static 属性或方法

问:定义一个赋值为 null 的类,变量名 a,能否通过 a 不进行实例化而直接访问其 static 属性或者方法?

答:答案是肯定的,能。譬如如下例子:

public class Test {
    public static int NUM = 100;

    public static void funcDo() {
        System.out.println("Num = "+ NUM);
    }

    public static void main(String[] args) {
        Test test = null;
        System.out.println(test.NUM);
        test.funcDo();
    }
}

上面代码的运行结果

100
Num = 100

不过不建议这么写代码。至于为什么其实很简单,直接看上面代码段的字节码,如下:

$ javap -v Test.class 
......
//编译后常量池已经替换成了与 null 无关而与类相关的 static 成员,#7 与 #12。
Constant pool:
   ......
   //重点!!!
   #7 = Fieldref           #13.#39        // Test.NUM:I
   ......
   //重点!!!
  #12 = Methodref          #13.#45        // Test.funcDo:()V
  #13 = Class              #46            // Test
  ......
{
  ......

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
          //把null入栈
         0: aconst_null
         1: astore_1
         2: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         5: aload_1
         6: pop
         //重点!使用了常量池的#7
         7: getstatic     #7                  // Field NUM:I
        10: invokevirtual #11                 // Method java/io/PrintStream.println:(I)V
        13: aload_1
        14: pop
        //重点!使用了常量池的#12
        15: invokestatic  #12                 // Method funcDo:()V
        18: return
      ......
}
SourceFile: "Test.java"

很明显可以看出,当我们通过一个对象的引用访问静态成员属性或者方法时,访问操作只与所声明的引用类型相关;与引用对象是否为 null 无关,因为访问静态成员不需要实例化对象;即便引用不为 null,也与运行时多态无关,因为静态成员是类相关的。

本文参考自
https://mp.weixin.qq.com/s/LDFbduPPO_hQDrt9XNGUaQ

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容