4

考虑这段代码:

class MyClass {
    private static MyClass myobj = new MyClass();

    private MyClass() {
    }

    public  static MyClass getMyobj() {
        return myobj;
    }
}

1)IN上面的代码什么时候myobj初始化——什么时候Myclass被加载或者什么时候getMyobj()第一次被调用MyClass.getMyobj();

2)假设我们调用两次:

MyClass.getMyobj();
MyClass.getMyobj();

MyClass()它会在第二次调用时创建新对象吗?

4

6 回答 6

2
  1. 何时加载您的课程

  2. 不,它不会创建另一个对象,它会使用已经存在的对象

于 2012-07-13T16:56:32.817 回答
1

正如已经指出的,该对象将在类初始化时创建,并且由于该方法只是返回它,因此在示例代码中不会创建其他此类实例。

但是,如果您想做这样的事情,您也可以enum使用单个实例创建一个:

public enum MyClass {
   myobj;
}

然后需要使用的代码myobj可以简单地访问该MyClass.myobj字段,而代码本身保留单例行为。当然,类似的效果可以用场来实现public static final

枚举的好处是编译器知道您不想意外创建任意对象。它的缺点是,如果您想要延迟初始化,则需要为延迟加载的部分引入一个额外的委托。

于 2012-07-13T17:06:56.307 回答
1

1)在上面的代码中,myobj什么时候会被初始化

首次加载类时。

2)假设我们调用两次:...它会在第二次调用时创建新的 MyClass() 对象吗?

不,主要是因为myobj它是静态的,所以getMyobj()总是会返回相同的实例,即在加载时创建的实例。

于 2012-07-13T16:56:38.517 回答
1
  1. 当 MyClass 被加载时。

  2. 即使你调用它十次,MyClass 也只存在一个实例。

于 2012-07-13T16:56:58.250 回答
0

说一个类在加载后就被初始化是不正确的。只有在运行程序创建该类的实例(通过使用 new 关键字调用其构造函数)或使用属于该类的任何静态方法或字段时,才会初始化一个类。

有关初始化的 JVM 规则,请参阅Java 语言规范第 12.4.1 节。

我应该指出,我之所以知道这一点,要归功于 Joshua Bloch 的优秀著作“Effective Java, Second Edition”。Item 71 提供了关于惰性初始化和“惰性初始化持有者类习语”的建议。

因此,在回答您的问题时,MyClass.myobj只会在正在运行的程序(例如您的main()方法)实际调用MyClass.getMyobj()而不是在那之前的时刻进行初始化。

并且因为静态字段每个类只初始化一次,所以下一次MyClass.getMyobj()调用时,它将简单地返回现有的值MyClass.myobj,因此您将获得对完全相同的 MyClass 对象的两个引用。

于 2012-07-14T12:32:35.930 回答
0

一旦 MyClass 被加载,它就会被初始化。但它只会初始化一次。

于 2012-07-13T16:58:34.190 回答