JavaSE面试题——类初始化 & 实例初始化

简介: JavaSE面试题——类初始化 & 实例初始化

1.Go!!!


以下代码的运行结果是:👇👇👇


运行结果如下:👇👇👇

分析:


1.    首先这道题它考查了:类的初始化、实例的初始化、方法重写、对象的多态性这些内容。

2.    类的初始化:

·       一个类要创建实例需要先加载并初始化该类(main方法所在的类要先进行加载和初始化)。

·       一个子类要加载并初始化,需要先加载并初始化它的父类。

·       一个类的初始化就是执行<clinit>()方法,<clinit>()方法由静态类变量显示赋值代码和静态代码块组成,同时<clinit>()方法只会执行一次,而静态类变量显示赋值代码和静态代码块的执行顺序是从上到下顺序执行(谁在前面先执行谁)。

     3. 实例初始化:

·       实例初始化就是执行<init>()方法,<init>()方法可能重载有多个,有几个构造器就有几个<init>()方法。

·       <init>()方法由非静态(实例变量)显示赋值代码和非静态代码块、对应的构造器组成。它们三者的执行顺序是:非静态(实例变量)显示赋值代码和非静态代码块从上到下顺序执行(谁在前面先执行谁),而对应的构造器则在最后执行。

·       每次创建实例对象,调用对应构造器,执行的就是对应的<init>方法。

·       <init>方法的首行是 super() super(实参列表),即对应会先执行父类的<init>方法。

      4.哪些方法不可以被重写?

·       final修饰的方法、静态方法、private等子类中不可见的方法。

      5.对象的多态性

·       子类如果重写了父类的某个方法,通过子类对象调用的一定是子类重写过的方法。

·       非静态方法默认的调用对象是 this

·       this对象在构造器或者说<init>方法中就是正在创建的对象。

public class Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.print("(1)");
    }
    Father() {
        System.out.print("(2)");
    }
    {
        System.out.print("(3)");
    }
    public int test() {
        System.out.print("(4)");
        return 1;
    }
    public static int method() {
        System.out.print("(5)");
        return 1;
    }
}
public class Son extends Father {
    private int i = test();
    private static int j = method();
    static {
        System.out.print("(6)");
    }
    Son() {
        System.out.print("(7)");
    }
    {
        System.out.print("(8)");
    }
    public int test() {
        System.out.print("(9)");
        return 1;
    }
    public static int method() {
        System.out.print("(10)");
        return 1;
    }
    //main方法所在的类需要先加载和初始化
    public static void main(String[] args) {
        Son s1 = new Son();
        System.out.println();
        Son s2 = new Son();
    }
}

这里先进行的是类初始化过程。

因为main方法在Son子类中,所以这里会先进行Son类的加载和初始化,而Son有一个父类Father,所以这里先对Father类进行加载和初始化。

先去执行Father类中的静态类变量显示赋值代码和静态代码块,因为静态类变量显示赋值代码 private static int j = method();位置更靠前,所以它先执行,而静态方法是不能被重写的,所以这里执行父类自己的method方法,首先输出(5)。然后继续执行父类的静态代码块,输出(1)。到此,父类的加载和初始化完成,转回子类进行加载和初始化。那么同父类一样,因为静态类变量显示赋值代码 private static int j = method();位置更靠前,所以它先执行,输出(10)。然后执行子类的静态代码块,输出(6)。即类初始化全部完成,目前输出了 (5)(1)(10)(6)


下面进行实例初始化过程。


因为<init>()方法的首行是 super(),所以此时仍然是先到父类中进行实例初始化:非静态(实例变量)显示赋值代码和非静态代码块,而非静态(实例变量)显示赋值代码位置更靠前,private int i = test();它先执行,而在非静态方法里面都有一个默认的对象this表示当前正在创建的对象,因为第一次实例初始化过程是由main方法中的 Son s1 = new Son(); 走过来的,所以当前this对象指的就是Son对象,也就是执行的其实应该是子类重写之后的test方法,即输出(9)。然后继续执行父类的非静态代码块,输出(3)。最后执行父类的无参构造,输出(2)。到此,父类的实例初始化完成,转回子类进行实例初始化。同父类一样,因为非静态(实例变量)显示赋值代码位置更靠前,private int i = test();它先执行,输出(9)。然后执行子类的非静态代码块,输出(8)。最后执行子类的无参构造,输出(7)。即目前输出了 (5)(1)(10)(6)(9)(3)(2)(9)(8)(7)


main中还有最后两行需要执行:System.out.println();   Son s2 = new Son();

首先打印一个换行,然后Sonnew了第二个对象,要进行了第二次实例初始化(类初始化只会进行一次),所以类初始化相关的静态类变量显示赋值代码和静态代码块不会再执行了,只会执行非静态(实例变量)显示赋值代码和非静态代码块。那么同上面分析的一样,先去父类进行实例初始化、然后回到子类进行实例初始化。最终第二次实例初始化完成:(9)(3)(2)(9)(8)(7)


即最终的结果就是:👇👇👇

(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)

(9)(3)(2)(9)(8)(7)

相关文章
|
5天前
|
SQL 数据库
SQL面试50题------(初始化工作、建立表格)
这篇文章提供了SQL面试中可能会遇到的50道题目的建表和初始化数据的SQL脚本,包括学生、教师、课程和成绩表的创建及数据插入示例。
SQL面试50题------(初始化工作、建立表格)
|
11天前
|
Java
Java 基础语法-面试题(54-63道)(数组+类+包)
Java 基础语法-面试题(54-63道)(数组+类+包)
29 16
|
1月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
67 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
1月前
|
安全 Java 开发者
Java面试题:什么是Java 15中的密封类以及其限制?还有哪些其他特性用于限制类继承的机制吗?
Java面试题:什么是Java 15中的密封类以及其限制?还有哪些其他特性用于限制类继承的机制吗?
23 1
|
1月前
|
存储 运维 前端开发
Java面试题:什么是Java的异常处理机制?列举常见的异常类,并说明使用场景
Java面试题:什么是Java的异常处理机制?列举常见的异常类,并说明使用场景
32 0
|
1月前
|
安全 Java 数据处理
Java面试题:什么是Java中的Optional类及其使用场景?
Java面试题:什么是Java中的Optional类及其使用场景?
24 0
|
1月前
|
前端开发 Java 编译器
Java面试题:描述Java类的加载过程,包括加载、链接、初始化等阶段。
Java面试题:描述Java类的加载过程,包括加载、链接、初始化等阶段。
19 0
|
4天前
|
存储 缓存 网络协议
复盘女朋友面试4个月的Java基础题
这篇文章是关于Java基础面试题的复盘,涵盖了HashMap原理、对象序列化作用等高频面试问题,并强调了Java基础知识的重要性。
复盘女朋友面试4个月的Java基础题
|
6天前
|
存储 NoSQL Java
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
这篇文章是关于Java面试中的分布式架构问题的笔记,包括分布式架构下的Session共享方案、RPC和RMI的理解、分布式ID生成方案、分布式锁解决方案以及分布式事务解决方案。
一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)
|
29天前
|
SQL Java Unix
Android经典面试题之Java中获取时间戳的方式有哪些?有什么区别?
在Java中获取时间戳有多种方式,包括`System.currentTimeMillis()`(毫秒级,适用于日志和计时)、`System.nanoTime()`(纳秒级,高精度计时)、`Instant.now().toEpochMilli()`(毫秒级,ISO-8601标准)和`Instant.now().getEpochSecond()`(秒级)。`Timestamp.valueOf(LocalDateTime.now()).getTime()`适用于数据库操作。选择方法取决于精度、用途和时间起点的需求。
32 3