考虑这段代码:
class MyClass {
private static MyClass myobj = new MyClass();
private MyClass() {
}
public static MyClass getMyobj() {
return myobj;
}
}
1)在上面的代码中,当myobj
加载Myclass
时加载getMyobj()
或第一次调用MyClass.getMyobj();
MyClass.getMyobj();
MyClass.getMyobj();
时会{}}
2)假设我们两次打电话:
MyClass()
它会在第二次调用时创建新的{{1}}对象吗?
答案 0 :(得分:2)
何时加载您的课程
不,它不会创建另一个对象,它将使用已存在的对象
答案 1 :(得分:1)
1)在上面的代码中myobj何时会被初始化
首次加载课程时。
2)假设我们调用两次:...它会在第二次调用时创建新的MyClass()对象吗?
否,主要是因为myobj
是静态的,所以getMyobj()
将始终返回相同的实例,即在加载时创建的实例。
答案 2 :(得分:1)
当MyClass加载时。
即使你召唤十次,MyClass也只有一个实例。
答案 3 :(得分:1)
正如已经指出的那样,该对象将在初始化类时创建,并且因为该方法只是返回它,所以在示例代码中不会创建其他此类实例。
但是,如果您想要做这样的事情,您还可以使用单个实例创建enum
:
public enum MyClass {
myobj;
}
然后,需要使用myobj
的代码只需访问MyClass.myobj
字段,而代码本身保留单例行为。当然,使用public static final
字段可以实现类似的效果。
枚举的好处是编译器知道你不想意外地创建任意对象。它有一个缺点,如果你想要延迟初始化,你需要为懒惰加载的部分引入一个额外的委托。
答案 4 :(得分:0)
加载MyClass后,它将被初始化。但它只会初始化一次。
答案 5 :(得分:0)
说一个类在加载后立即初始化是不正确的。只有在正在运行的程序创建该类的实例(通过使用new关键字调用其构造函数)或者使用属于该类的任何静态方法或字段时,才会初始化类。
有关初始化的JVM规则,请参阅Java Language Specification section 12.4.1。
我应该指出,我只知道这要归功于Joshua Bloch的优秀着作“Effective Java,Second Edition”。第71项提供了有关延迟初始化和“延迟初始化持有者类习惯用语”的建议。
因此,在回答您的问题时,MyClass.myobj
只会在正在运行的程序(例如您的main()
方法)实际调用MyClass.getMyobj()
而不是之前的某个时刻进行初始化然后
因为静态字段每个类只初始化一次,所以下次调用MyClass.getMyobj()
时,它只会返回MyClass.myobj
的现有值,因此您将获得两个完全相同的MyClass的引用对象