JAVA面试:深入解析类初始化顺序与对象创建

需积分: 10 2 下载量 64 浏览量 更新于2025-01-05 收藏 573KB PDF 举报
"JAVA面试题解惑系列,深入解析了JAVA面试中常见的问题,包括类的初始化顺序、字符串对象的创建以及参数传递是值还是引用等核心知识点。" 在JAVA面试中,掌握类的初始化顺序是非常关键的一个部分,因为它直接影响到程序的执行逻辑和变量的赋值状态。在JAVA中,类的初始化顺序遵循以下规则: 1. **静态变量与静态初始化块**:首先执行父类的静态变量和静态初始化块,然后执行子类的静态变量和静态初始化块。这是因为静态成员属于类级别,不依赖于类的实例,所以在类加载时就完成了初始化。 ```java class Parent { public static String p_StaticField = "父类--静态变量"; // ... static { System.out.println(p_StaticField); // 父类静态变量初始化 } } class Child extends Parent { public static String c_StaticField = "子类--静态变量"; // ... static { System.out.println(c_StaticField); // 子类静态变量初始化 } } ``` 2. **非静态变量与非静态初始化块**:接下来是实例变量和实例初始化块(也叫构造块),这部分的执行顺序取决于实例的创建。当创建子类的实例时,会先调用父类的构造器,因此父类的实例变量和构造块会在子类之前执行。 ```java class Parent { public String p_Field = "父类--变量"; // ... { System.out.println(p_Field); // 父类实例变量初始化 } public Parent() { System.out.println("父类构造器"); } } class Child extends Parent { public String c_Field = "子类--变量"; // ... { System.out.println(c_Field); // 子类实例变量初始化 } public Child() { System.out.println("子类构造器"); } } ``` 3. **构造器**:最后是调用构造器。在子类实例创建过程中,会先调用父类的构造器,然后执行子类的构造器。这是为了确保父类的状态正确初始化,然后再处理子类的状态。 当我们创建一个`Child`类的实例时,输出顺序会是: 1. 父类的静态变量和静态初始化块 2. 子类的静态变量和静态初始化块 3. 父类的实例变量和初始化块 4. 调用父类的构造器 5. 子类的实例变量和初始化块 6. 调用子类的构造器 另一个常见面试问题是关于`String`对象的创建。在JAVA中,`String`对象是不可变的,每次对`String`进行修改都会创建一个新的对象。例如,`String s = "abc" + "def"`实际上会创建两个`String`对象,一个是`"abc"`,另一个是`"abcdef"`,而不是直接连接原来的字符串。这种行为是由于`String`池和字面量连接优化的结果。 此外,JAVA中的参数传递总是按值传递,这意味着函数不能直接改变传入的引用变量指向的对象。例如,如果传递一个对象引用,函数内部对该对象的修改会生效,但不能改变引用本身。理解这些基础概念对于解答JAVA面试题至关重要。