通过类创建对象、对象内存管理(学习堆和方法区)

是现实世界当中具有共同特征的事物进行抽象形成的模板或概念。而对象是实际存在的个体。

例如:“汽车”就是一个类(所有的汽车都有方向盘、发动机、都能形式,这是它们的共同特征),“你家的那个汽车”就是一个真实存在的对象。或者说“明星”是一个类,“刘德华”就是一个对象。“鹿晗”、“吴亦凡”、“蔡徐坤”都是实际存在的对象。

那么“明星”类都有哪些共同特征呢?明星类都有姓名、性别、年龄等状态信息(属性),他们还有一个共同的行为就是“演出”(方法)。

通过类可以创建对象,对象又被称为实例(instance),这个过程也可以称为实例化。对象1、2、3 具有共同特征,进行抽象形成了类,所以从对象到类称为抽象。如下图所示:

 我们得知:类 = 属性 + 方法,而属性描述的是状态,方法描述的是行为动作。

其中id、name、age 都是属性,它们都是类中的成员变量(深入说是成员变量中的实例变量),所谓实例变量就是对象级别的变量,这些属性要想访问,必须先创建对象才能访问,不能直接通过类去访问。

其中study()是一个方法,但是这个方法是不加static关键字的,这个方法是实例方法,必须先创建对象才能访问,不能直接通过类去访问。

-----------------------------------------------------

//创建一个模板类Person
public class Person {
    String sex;
    double height;
    int age;
    String name;

    public void call(){
        System.out.println("打电话------");
    }
    public void sendMessage(){
        System.out.println("发信息------");
    }
}
public class TestPerson {
    public static void main(String[] args) {
        //创建一个Person对象
        Person p1 = new Person();
        //再创建一个Person对象
        Person p2 = new Person();
        //以上代码其实跟这行代码差不多
        int i = 10;
    }
}

 代码解读:

对于int i = 10 来说,int 是一种基本数据类型,i 是变量名,10 是int 类型的字面量。

对于Student s1 = new Student()来说,Student 是一种引用数据类型,s1 是变量名,new Student()执行之后是一个Student 类型的对象。

---------------------------------------------------

java 语言当中,当实例变量没有手动赋值在创建对象的时候,也就是说在 new 的时候,系统会对实例变量默认赋值,它们的默认值请参考下表:

 

-------------------------------------------------------

 对象内存管理--学习堆和方法区

 1)java 堆

概念:是被所有线程共享的一块区域,在虚拟机启动时创建。

特点:线程共享,存放的是对象实例(所有的对象实例和数组),GC 管理的主要区域。可以处于物理上不连续的内存空间。

2)方法区

概念:存储已被虚拟机加载的类信息、常量、静态变量,即时编译器编译后的代码等数据。

//方法区中存储类的信息(即代码片段)。所有程序的执行,必须入栈执行!

特点:线程共享的区域,当方法区无法满足内存分配需求的时候,会抛出异常OutOfMemory 异常。 

大概了解了java 虚拟机内存分配之后,来看看以下代码在执行过程中,内存是如何变化的,例如有如下代码:

以上代码在执行过程中内存的变化如下图所示:

第一步执行类加载

 

第二步main 方法调用,给main 方法分配栈帧(压栈)

 

第三步执行int i = 10,局部变量

 

第四步执行new Student(),在堆中创建对象,同时初始化实例变量

 

第五步将堆区中学生对象的内存地址赋值给局部变量s1

上图堆区中“对象”创建完成之后,该对象在堆区当中的内存地址是:0x1111,程序中的“=”将0x1111 这个堆内存地址赋值给s1 变量,也就是说s1 变量保存了堆内存对象的内存地址,我们对于这种变量有一种特殊的称呼,叫做“引用”。也就是说对于Student s1 = new Student()代码来说,s1 不是对象,是一个引用,对象实际上是在堆区当中,s1 变量持有这个对象的内存地址。

如果是创建多个对象,例如有如下代码:

内存分配如图所示:

值得大家注意的是,java 中没有指针的概念(指针是C 语言当中的机制),所以java 程序员没有权利直接操作堆内存,只能通过“引用”去访问堆内存中的对象,例如:s1.no、s1.name、s1.sex、s1.age。

访问一个对象的内存,其实就是访问该对象的实例变量,而访问实例变量通常包括两种形式,要么就是读取数据,要么就是修改数据,例如:System.out.println(s1.no)这就是读取数据,s1.no = 100 这就是修改数据。

posted @ 2022-03-02 10:30  鹿先森JIAN  阅读(180)  评论(0编辑  收藏  举报