Java 类的加载过程

1.栈、堆、方法区分别存放什么

栈: 用来运行函数。可以存储局部信息
堆:用来存储new出来的实体 (特点:每一个实体所开辟的空间都有一个地址;每一个实体中存储的数据都有一个默认初始值)
方法区:存放.class和static (方法区其实是由N多个小的区域构成。有存放非静态内容的非静态区域,还有存放静态内容的静态区域,还有存放常量的常量池等)

2.类加载过程

  1. JVM会先去方法区中找有没有相应类的.class存在。如果有,就直接使用;如果没有,则把相关类的.class加载到方法区
  2. 在.class加载到方法区时,会分为两部分加载:先加载非静态内容,再加载静态内容
    1). 把.class中的所有非静态内容加载到方法区下的非静态区域内
    2). 加载静态内容:
    2.2.1. 把.class中的所有静态内容加载到方法区下的静态区域内
    2.2.2. 对所有的静态变量进行默认初始化
    2.2.3. 对静态变量进行显式初始化
    2.2.4. 执行静态代码块

3.对象创建过程

  1. 在堆内存中开辟一块空间
  2. 给开辟空间分配一个地址
  3. 把对象的所有非静态成员加载到所开辟的空间下
  4. 对所有非静态成员变量进行默认初始化
  5. 调用构造函数,分为两部分:
    先执行构造函数中的隐式三步,再执行构造函数中书写的代码。
    1)隐式三步:
    1,执行super语句
    2,对开辟空间下的所有非静态成员变量进行显式初始化
    3,执行构造代码块
    2)执行构造函数中书写的代码
  6. 把空间分配的地址赋值给一个引用对象

举例

class Person {  
    int age;  

    Person(int age) {  
        this.age = age;  
    }  
}  

class Student extends Person {  
    // 2、对开辟空间下的所有非静态成员变量进行显式初始化  
    String school = "abc";  

    Student(String school, int age) {  
        // 1、执行super语句  
        super(age);  
        // 4、在隐式三步执行完之后,执行构造函数中书写的代码  
        this.school = school;  
    }  

    {  
        // 3、执行构造代码块  
        System.out.println("Student code block");  
    }  
}  

4.Person p= new Person();在内存中做了什么?

A:将Person.class文件加载到内存中。
B:在堆内存中创建一个对象Person。
C:把Person中的属性进行默认初始化。
D:把Person中的属性进行显式初始化。
E:调用构造代码块
F:调用构造函数进行初始化。
G:在栈内存中声明Person类型的变量p。
H:把堆内存的地址(引用)赋给了栈内存中p。

5.一道奇葩的题目不知道你会不会哦?

class SingleTon {
    private static SingleTon singleTon = new SingleTon();
    public static int count1;
    public static int count2 = 0;

    private SingleTon() {
        count1++;
        count2++;
    }

    public static SingleTon getInstance() {
        return singleTon;
    }
}

public class Test {
    public static void main(String[] args) {
        SingleTon singleTon = SingleTon.getInstance();
        System.out.println("count1=" + singleTon.count1);
        System.out.println("count2=" + singleTon.count2);
    }
}

打印:
count1=1

count2=0

分析:
1.SingleTon singleTon = SingleTon.getInstance();调用类SingleTon的静态方法,触发了类的初始化
2. 类加载时在准备过程中为类的静态变量分配内存并初始化默认值 singleton=null count1=0,count2=0
3. 类初始化后,为类的静态变量赋值和执行静态代码快。singleton赋值为new SingleTon()调用类的构造方法
4. 调用类的构造方法后count1和count2都要自增加1,因此count=1 count2=1
5. 执行打印语句:继续为count1与count2赋值,此时count1没有赋值操作,因此count1为1,但是count2执行赋值操作就变为0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值