JAVA单例模式的延迟加载疑问

2025-03-10 01:13:51
推荐回答(4个)
回答1:

1.首先 所有的类都是第一次被引用时才会加载到JVM中。也就是说全都是延迟加载,而不是预先加载。
2.“静态类将只会随JVM装载一次,所以只会创建一个Foo对象”,这句话的意思是说,随着类LazyFoo被第一次引用,JVM会载入类LazyFoo,同时执行类的静态初始化。
什么是类的静态初始化?
类被载入JVM之后,各个语句之间的执行顺序是如何的呢?
#当第一次引用类之后#
1.类的静态初始化(包括类的静态块)
#当创建类的对象后#
2.类的非静态初始化(同样包括类的非静态块)
3.类的构造函数

public static Foo foo = new Foo();
这一句就是类的静态初始化,他仅会在类被载入时执行一次。

实际上你的这个单例模式的代码还是有些问题的。似乎不能达成单例效果,除非添加一个private Foo()构造函数。

我写一个单例模式给你看看吧。
public class Foo {
private static Foo sc;

private Foo() {

}

public static Foo getSC() {
if (sc == null) {
sc = new Foo();
}
return sc;
}
}

回答2:

怎么加载楼上说的蛮清楚的我给你演示下。
首先你列出的那个类不是单列模式。
必须将Foo类构造方法私有化,在Foo中添加 private Foo(){}
public class Foo {

private Foo(){

}
static{
//主类的静态块,在该类加载时运行
System.out.println("外部类被加载");
}
public int a;
public static int b = 22;
// 私有静态内部类, 只有当有引用时, 该类才会被装载
private static class LazyFoo {
static{
//内部类的静态块,在该类加载时运行
System.out.println("内部类被加载Foo.b = " + Foo.b);
}
public static Foo foo = new Foo();

}

public static Foo getInstance() {
return LazyFoo.foo;
}

public void setA(int a){
this.a = a;
}

public int getA(){
return this.a;
}
}

public class Test{
public static void main(String[] args) throws Exception {
System.out.println(Foo.b); //运行这句,可以看到外部类已加载,但内部类为加载。
//Foo a = Foo.getInstance(); //注销上面那句,运行这句,可以发现Foo类和其内部类都被加载。原因就如楼上所说,所有类都是被引用才加载。

}
}

回答3:

上面的这段代码貌似存在问题,单例模式是将构造器私有,防止创建多个这个类的对象。然后只提供一个方法来获取这个类的对象。并且只提供一个对象,如果对象已经存在,则不允许创建。这个是单例模式。静态的类执行效率都比较高,JVM执行的时候首先执行静态的类,main方法是静态的就可以知道使用static的效果了。static类在调用的时候才开始装载

回答4:

你这个 不是单例模式。。。。。。
单例模式满足的条件有2个,
第一 私有的构造方法//作用,不允许其他类调用构造方法
第二 一个属性为自己的静态变量
给你一个最简单的单例模式来分析一下吧
class A{
private A(){
}
public static A a = new A();
}
1,首先A这个类拥有一个私有的构造方法,也就是其他类没有办法实例化A这个类,
2,这个类拥有一个静态的属性,值为 new A();因为该属性是静态的,所以jvm一开始的时候就会执行一次new A()的方法,

单例完成,其他类无法实例化该类,该类启动的时候被自己实例化了一次,所以系统中就只有一个了,