初始化类变量

  • 本文关键字:类变量 初始化 java
  • 更新时间 :
  • 英文 :


我在一个maven项目中有4个java类

Test1
Test2
Test3
Test4

Test4类具有以下静态变量和静态方法:

private static Test4 instance=new Test4();
public static Test4 getInstance(){
return instance;
}

这个函数是从Test1、Test2和Test3类调用的,我会得到相同的实例值,例如:Test4@7dfda.

当这个函数getInstance((第一次从Test1调用时,它可能已经初始化了Test4类,并初始化了作为实例的静态类变量。当这个函数再次从Test2或Test3类调用时,它的行为会不会是一样的,每次都应该返回实例的新值?

这是一个已损坏的单例实现。instance字段本应设置为final

每当JVM执行代码时,它首先扫描VM将要执行的方法中提到的所有各种类型。然后,它首先查找所有这些类型,向相关的类加载器询问这些类。

换句话说,当你有:

class Example {
public static void main(String[] args) {
new Test1();
System.out.println(Test2.someStaticMethod());
System.out.println(Test3.class.getName());
}
}

并且要执行main,首先VM进行扫描,并意识到它需要加载Test1、Test2和Test3,否则这将不起作用。因此,VM向相关的类加载器(因为这是我们所说的"main",是使用类路径的默认应用程序加载器(询问Test1、Test2和Test3。

类加载器的作用就像一个大的hashmap,将类名映射到加载的等价项。因此,如果已经加载了Test1、Test2或Test3,它们只会立即返回已经加载的类。如果未加载,则会变得更有趣。

然而,加载Test1将反过来导致检索Test4(也就是说,如果Test1的初始化本身调用Test4。如果Test1的构造函数和初始化器对Test4没有任何作用,那么加载Test1将不会导致加载Test4(。Test4还没有加载,所以它将被加载。加载Test2将再次导致检索Test4,但它已被加载。

作为实际加载类的一部分,所有静态初始化程序都会运行;那就是new Test4()的结局。假设一个类只加载一次,那么private static Test4 instance = new Test4()中的new Test4()只执行一次。

当然,如果new Test4()在VM的生命周期中只执行过一次,那么只能有一个Test4实例。

一个合适的单例的完整代码是:

public class Test4 {
// important: a private constructor,
// to ensure nobody can make instances.
private Test4() {}
private static final Test4 INSTANCE = new Test4();
public static Test4 get() { return instance; }
}

因此,您观察到的是正确的:getInstance((返回instance,并且实例只初始化一次:第一次任何人调用getInstance(),或者更确切地说,就在那之前:第一次执行任何方法,其主体使用Test4执行某些操作(除了调用getInstance()之外,它还能做什么?很可能什么都没有(。

注:

制作单身汉的创造性和几乎总是破碎或不必要的复杂方式是非常常见的。这是一个有1000个单词的单词,意思是雪/飞机飞,因为机翼下的空气比机翼上的快/如果你慢慢增加热量,青蛙就会呆在锅里。因此,如果你在网上疯狂搜索单身人士,请注意,你会发现大多数帖子都是错误的。

这里的主要问题是"实例";对象(和"getInstance"方法(是Static

静态方法/成员共享给该方法的所有调用,而不考虑正在使用的特定对象

最新更新