Java 执行顺序、静态块、字段

Java 执行顺序、静态块、字段,java,static,block,Java,Static,Block,我知道静态块比任何东西都要先运行。但是在这里,调用B.test()时会发生什么?执行顺序和值的设置?后来,当b1被设置为null时,b1.i如何计算为20 class B { static int i; static { i = 20; System.out.println("SIB"); } static int test() { int i = 24; System.

我知道静态块比任何东西都要先运行。但是在这里,调用B.test()时会发生什么?执行顺序和值的设置?后来,当b1被设置为null时,b1.i如何计算为20

class  B
{    
     static int i;
     static {
         i = 20;
         System.out.println("SIB");
     }
     static int test() {  
         int i = 24;
         System.out.println(i);
         return i; 
     }
}

public class Manager {
    public static void main(String[] arg) {
         B.test();
         B b1 = null;
         System.out.println(b1.i);  
    }
}
输出为:

SIB
24
20

i
是静态的,因此
b1.i
相当于
B.i
。仅将
b1
设置为
null
不会更改任何静态变量

调用
B.test()
时,首先加载
B
类,并运行静态块。接下来,
B.test()
创建一个名为
i
的新方法局部变量,它与
B.i
完全不同。打印并返回此新的本地
i
。不会对
B.i
进行任何更改,当然不仅仅是因为您创建了一个新的
B
对象引用,该引用为null,这对任何事情都不会有任何影响

但是在这里,调用B.test()时会发生什么?执行顺序和值的设置

没有变化

后来,当b1被设置为null时,b1.i如何计算为20

class  B
{    
     static int i;
     static {
         i = 20;
         System.out.println("SIB");
     }
     static int test() {  
         int i = 24;
         System.out.println(i);
         return i; 
     }
}

public class Manager {
    public static void main(String[] arg) {
         B.test();
         B b1 = null;
         System.out.println(b1.i);  
    }
}

由于未使用
b1
,因此该字段是静态的,因此您实际使用的是
B.i
此处的
i

static int i;
static {
    i = 20;
    System.out.println("SIB");
}
设置为20并且从不修改,因此当您访问
b1.i
时,它仍然是
20

test()
方法中,您正在使用另一个与静态变量无关的
i
变量。

发生的情况是:

  • B.test()
    在实际运行之前第一次被调用:
  • B
    已加载
  • 已执行静态初始值设定项(
    B.i=20
    now)
  • 执行
    B.test()
    方法的内容
  • (创建一个本地方法
    int i=24
    (该方法对静态变量
    B.i
    进行阴影处理)并打印它)
  • b1.i
    被解释为
    B.i
    (它仍然是
    20
    )并被打印出来

B.test没有设置任何静态或实例变量,因此调用它不会产生长期影响。(仔细阅读。)顺便说一句,从非静态引用(如b1实例)访问静态成员是一种不好的做法。谢谢,但当b1设置为null时,它应该存储,不指向任何内容。b1不应该。我给出了nullPointerException,因为b1没有引用任何内容,它不会引用像i或其他字段那样的内部值?引用静态字段就像引用实例变量一样有点可笑,但基本上,如果引用
instance.staticField
,它将完全忽略
实例的值
——即使它为null。谢谢,但是当b1设置为null时,它应该存储,指向nothing。我给出了nullPointerException,因为b1不引用任何内容,所以它不会像i或其他字段那样引用内部值?b1.i-->null.i?不,您正在访问一个静态变量,它存储在类中,而不是实例中。编译器实际上只是查看
b1
类,发现您正在访问
B.i
。它从不尝试对实例执行任何操作。