【问题标题】:Static variable initialization in Constructor java构造函数java中的静态变量初始化
【发布时间】:2012-05-09 13:32:40
【问题描述】:

我想从下面的代码中了解静态变量 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();
       }
    }

谢谢 普尼斯

【问题讨论】:

标签: java static constructor


【解决方案1】:

错误 - 这样做:

public class A {
       private static B b = null;

       static {
             b = new B();
       }

       public A() {
       }

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

【讨论】:

  • 我敢肯定,如果您能详细说明为什么在发布的 OP 中这样做是错误的,那将会更有帮助。
  • 但这在语义上是不同的,对吧?在 OP 发布的代码中,除非实际创建对象,否则不会初始化该字段。
  • 伙计们,我想知道在调用 main 方法之前会调用构造函数。所以对象将被初始化。还是上面的说法是假的??
  • 为实例调用构造函数,而不是静态变量。
  • 不,在main() 之前没有调用构造函数,顺便说一句,您可以简单地添加System.out.println() 来测试这些东西;-)
【解决方案2】:

你永远不会调用 A() 构造函数。 main 函数是静态的,这意味着它不“属于” A 的实例。 所以当你进入 main 时,没有创建 A 的实例,所以 A 的构造函数从未被调用过,b 仍然为 null。

如果你运行这段代码,你应该得到一个 NullPointerException。

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

【讨论】:

    【解决方案3】:

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

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

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

    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();
           }
        }
    

    【讨论】:

      【解决方案4】:

      您的问题旨在帮助您“理解为什么”该行为会如此。原因是调用静态方法main()时没有调用A类的构造函数。

      如果您要实例化一个 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()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-01-03
        • 2014-10-23
        • 1970-01-01
        • 2011-02-15
        • 1970-01-01
        • 2010-12-11
        • 1970-01-01
        相关资源
        最近更新 更多