2

我想从下面的代码中了解静态变量 b 的值未初始化,尽管该值已在构造函数中初始化。

public class A {
       private static B b = null;
       public A() {
           if (b == null)
             b = new B();
       }

       public static void main(String[] args) {
           b.func();
       }
    }

谢谢普尼斯

4

4 回答 4

7

错误 - 这样做:

public class A {
       private static B b = null;

       static {
             b = new B();
       }

       public A() {
       }

       public static void main(String[] args) {
           b.func();
       }
    }
于 2012-05-09T13:34:24.287 回答
6

你永远不会调用 A() 构造函数。main 函数是静态的,这意味着它不“属于” A 的实例。因此,当您输入 main 时,没有创建 A 的实例,因此从未调用过 A 构造函数并且 b 仍然为空。

如果运行此代码,您应该得到 NullPointerException。

如果添加 new A(); 在 b.func() 之前;那么你会没事的(代码仍然很奇怪)

于 2012-05-09T13:36:32.913 回答
3

我认为你的问题有两个部分:

1) 为什么静态变量 b 的值没有被初始化,而值是在构造函数中初始化的?

Ans: 首先是在 main() 之前没有调用构造函数。在 main() 中调用构造函数。每当在 main() 中,您使用newas :

public static void main(String args[]){
MyClass myclass= new MyClass()
}

然后只调用构造函数。

在您的代码中,静态变量 b 未初始化,因为您在构造函数 A() 中对其进行了初始化,但从未调用过此构造函数。您可以在代码中调用 A() 构造函数:

public static void main(String[] args) {
          A a=new A(); // constructor gets called here.
           b.func();
       }

2)初始化静态变量的正确方法是什么?

初始化静态变量的正确方法是使用静态初始化块,而不是在构造函数中初始化它们,如上面 duffymo 给出的答案所示。

static {
  b = new B();
 }

您还可以使用:

public class A {
       private static B b = new B();

       public A() {
       }

       public static void main(String[] args) {
           b.func();
       }
    }
于 2012-11-30T07:30:13.203 回答
2

你的问题是为了帮助你“理解为什么”行为是这样的。原因是调用静态方法时不会调用 Class A 的构造函数main()

如果您要实例化一个类型的对象,A那么将调用构造函数并引用B初始化。

我建议总是在执行之前实例化一个类,这static void main()是一个好的做法。如果您开始使用框架(例如 Spring),您最好创建类的实例,而不是仅仅编写类似于编写过程代码的静态方法。

不使用静态初始化程序并遵循此处的原则大纲的解决方案是......

public class A {
    private static B b = null;

    public A() {
        if (b == null)
          b = new B();
    }

    public static void main(String[] args) {
        A a = new A();
        a.callFunc();
    }

    public void callFunc() {
        b.func();
    }
}

如您所见,您需要一种引用的方法,因此b.func() method我添加了一个a.callFunc()

于 2012-05-09T13:48:47.047 回答