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,也与运行时多态无关,因为静态成员是类相关的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值