java static加载顺序

为啥这个book(3)会被输出两次啊

public class demo6 {
    
    public static void main(String[] args) {
        System.out.println("1");
    }
    static Table table=new Table();
    static book b3=new book(3);
}
class book {
    public book(int num) {
        System.out.println("book("+num+")");
    }
    static Table t2=new Table();
}
class Table{
    static book b3=new book(3);//而且为什么book3不最先输出
    static book b1=new book(1);
    public Table() {
        System.out.println("Table");
    }
    book b2=new book(2);
}

//运行截图

img

答案参考Chatgpt解答
在这段代码中,book(3)被输出两次的原因是因为在Table类中有两个静态成员b3。一个是在声明Table类时初始化的静态成员b3,另一个是在Table类的构造函数中初始化的局部变量b3

静态成员是在类加载时初始化的,因此当类被加载时,book(3)会被输出一次。而在构造函数中初始化的局部变量b3,每次创建Table对象时都会执行一次,所以book(3)会再次被输出。

至于为什么book(3)不是最先输出,是因为在类加载时,静态成员的初始化是按照声明的顺序进行的。所以在初始化Table类时,先执行了静态成员b1的初始化,然后是静态成员b3的初始化。

如果你希望book(3)只输出一次,并且希望它最先输出,可以将静态成员b3的声明和初始化放在Table类的前面,如下所示:

class Table {
    static book b3 = new book(3);
    static book b1 = new book(1);

    public Table() {
        System.out.println("Table");
    }

    book b2 = new book(2);
}
  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7527856
  • 以下回答由chatgpt基于相关博客总结生成:

    在Java中,当使用静态块初始化类中的静态变量时,静态块会在静态变量之前被加载。因此,当静态变量和静态块都需要初始化时,应该将静态块放在静态变量之前。

    出现重复输出的原因可能是由于代码中重复使用了同一静态变量,导致输出结果重复。为了避免这种情况,可以考虑使用工厂模式,生成不同的对象实例来避免重复使用同一静态变量。

    以下是一个示例代码片段,用于展示如何使用工厂模式来避免重复使用静态变量:

    public class Example {
        private static Map<String, Example> instances = new HashMap<String, Example>();
        private static int count = 0;
    
        public static Example getInstance(String name) {
            if (!instances.containsKey(name)) {
                Example instance = new Example();
                instances.put(name, instance);
                return instance;
            }
            return instances.get(name);
        }
    
        private Example() {
            count++;
        }
    
        public void printCount() {
            System.out.println("Count: " + count);
        }
    }
    

    在这个示例中,我们使用一个静态的 Map 来存储生成的对象实例。当需要获取对象实例时,我们首先检查 Map 中是否已经存在相应的实例,如果存在,直接返回实例;如果不存在,创建新的实例并存储到 Map 中,再返回实例。

    这样就可以避免重复使用同一静态变量导致输出结果重复的问题。我们可以使用以下代码来测试:

    Example example1 = Example.getInstance("example1");
    Example example2 = Example.getInstance("example2");
    example1.printCount(); // 输出 Count: 1
    example2.printCount(); // 输出 Count: 2
    

    这里我们生成两个不同的对象实例,并观察它们的 count 值是否正确输出。