Java对象的创建和使用、代码实例内存分析与java虚拟机

OOTest01

首先我们看一个学生类:
学生类是一个模板,描述了所有学生得共同特征(状态+行为),当前类只描述学生的状态信息(属性)。

public class Student {
	//Student是类,属于引用数据类型,这个类型名就是:Student
	
	//类体=属性+方法
	//属性(存储数据采用变量的形式)
	//由于变量定义在类体当中,方法体之外,这种变量成为成员变量
	//所有学生都有学号信息,但是每一个学生的学号都是不同的
	//所以要访问这个学号必须先创建对象,通过对象去访问学号信息
	//学号信息不能直接通过类去访问,所以这种成员变量又叫做:实例变量
	//对象又被称作实例,实例变量又被称为对象变量(对象级别的变量)
	//不创建对象,这个no变量的内存空间是不存在的,只有创建了对象,这个no变量内存空间才会创建
	
	int no;//学号
	String name;//姓名
	int age;//年龄
	Boolean sex;//性别
	String addr;//住址
}

如果成员变量没有手动赋值的话,系统就会赋默认值

数据类型默认值
byte,short,long,int0
float,double0.0
booleanfalse
char\u0000
引用数据类型null

那么,我们进行java对象的创建和引用吧:
首先我要说的是:

  • 通过一个类可以实例化n个对象
  • 实例化对象的语法:new 类名();
  • new是Java语言中的一个运算符,它的作用是创建对象,在JVM堆内存中开辟新的内存空间

而java虚拟机内有三大块:

  • 方法区内存:在类加载的时候,class字节码文件代码片段被加载到该内存空间中
  • 栈内存(局部变量):方法代码片段执行的时候,会给该方法分配内存空间,在栈内存中压栈
  • 堆内存:new的对象在堆内存中存储
public class OOTest01 {

	public static void main(String[] args) {
		
		//int i=10;
		//int是基本数据类型
		//i是一个变量名
		//10是一个int类型的字面值
		
		
		Student s=new Student();//[^1]
		//Student是一个引用数据类型,s是一个变量名
		//new Student()是一个学生对象
		//s是局部变量,在栈中存储
		//什么是对象?new运算符在堆内存中开辟的内存空间称为对象
		//什么是对象引用?对象引用是一个变量,只不过这个变量中保存了另一个Java对象的内存地址
		//java程序员要想访问堆内存当中的对象内部的实例变量,必须得通过引用,和c不一样,c只需要用指针便可以
		
        //访问实例变量的语法格式:
		//读取数据:引用.变量名
		//修改数据:引用.变量名=值
		int stuNo=s.no;
		String stuName=s.name;
		int stuAge=s.age;
		boolean stuSex=s.sex;
		String stuAddr=s.addr;
		
		System.out.println("学号:"+stuNo);//0
		System.out.println("姓名:"+stuName);//null
		System.out.println("年龄:"+stuAge);//0
		System.out.println("性别:"+stuSex);//false
		System.out.println("住址:"+stuAddr);//null
		
		
		
		s.no=10;
		s.name="奥特曼";
		s.age=45000;
		s.sex=true;
		s.addr="光之国";
		
		System.out.println("学号:"+s.no);//10
		System.out.println("姓名:"+s.name);//奥特曼
		System.out.println("年龄:"+s.age);//45000
		System.out.println("性别:"+s.sex);//true
		System.out.println("住址:"+s.addr);//光之国
		
		//再通过类实例化一个全新的对象
		Student stu=new Student();
		//stu同时也是一个局部变量
		//Student是变量的数据类型
		
		System.out.println(stu.no);
		System.out.println(stu.name);
		System.out.println(stu.age);
		System.out.println(stu.sex);
		System.out.println(stu.addr);
		
		//System.out.println(Student.addr);
		//此时编译报错,因为addr是实例变量,对象级别的变量,变量存储在java对象的内部,必须先有对象
		//通过对象才能访问addr这个实例变量,不能直接通过类名
	}

}

这里,局部变量在栈内存中存储
成员变量中的实例变量在堆内存中的java对象内部存储
实例变量是一个对象一份,一百个对象一百份

给出当程序执行到Student s=new Student();时的内存图
在这里插入图片描述

给出访问实例变量时的内存图
在这里插入图片描述

给出又通过类实例化一个新对象后的内存图
在这里插入图片描述

OOTest02

下面我们创建一个用户类和家庭住址类:
用户类:

//用户类
public class User {
	//属性(以下是成员变量之实例变量)
	
	//用户编号
	int no;
	//int是一种基本数据类型:整数型
	//no是一个实例变量
	
	//用户名
	String name;
	//String是一种引用数据类型:代表字符串
	//name是一个实例变量
	//name是一个引用
	
	//家庭住址
	Address addr;
	//Address是一种引用数据类型:代表家庭住址
	//addr是一个实例变量
	//addr是一个引用
    //引用是一个变量,变量里面保存了内存地址,地址指向了一个对象
}

家庭住址类:

//家庭住址类
public class Address {
	
	//属性(成员变量之实例变量)
	//城市
	//String是一种引用数据类型,city是一个变量名,属于实例变量
	//city是一个引用:保存内存地址的一个变量,该变量保存内存地址指向了堆内存当中的对象
	
	//城市
	String city;
	//街道
	String street;
	//邮编
	String zipcode;

}

OOTest02类:

public class OOTest02 {
	public static void main(String[] args) {
		//创建user对象
		
		User u=new User();
		//u是局部变量,是一个引用
		//u保存内存地址指向堆内存的User对象
		
		//输出User对象内部实例变量的值
		System.out.println(u.no+" "+u.name+" "+u.addr);
		
		//修改User对象内部实例变量的值
		u.no=12;
		u.name="jack";//字符串比较特殊,不用new
		u.addr=new Address();
		
		//在main方法当中目前只能看到一个引用"u",
		//一切都是只能通过u来访问
		System.out.println(u.name+"居住在的城市为"+u.addr.city);
		u.addr.city="武汉";
		System.out.println(u.name+"居住在的城市为"+u.addr.city);
	}

}

给出OOTest02的内存图
在这里插入图片描述

OOTest03

public class OOTest03 {
	public static void main(String[] args) {
		//u是引用
		//u是局部变量
		User u=new User();
		
		//u.addr=new Address();
		
		//a是引用,是局部变量
		Address a=new Address();
		u.addr=a;
		System.out.println(u.addr.city);//null
		
		a.city="北京";
		System.out.println(u.addr.city);//北京
	}

}

在这里插入图片描述

OOTest04:空指针异常

我们现在再说一下空指针异常这个比较常见的错误
创建一个简单的顾客类:

//顾客类
public class Customer {
	//id
	int id;

}

OOTest04类:

public class OOTest04 {

	public static void main(String[] args) {
		Customer c=new Customer();
		System.out.println(c.id);//0
		
		c=null;
		
		//以下程序运行出现空指针异常
		//空引用访问“实例”相关的数据一定会出现空指针异常
		//即java.lang.NUllPointerExcepation错误
		//System.out.println(c.id);

	}

}
//“实例”相关的数据表示:这个数据访问的时候必须有对象的参与

内存图如下:
在这里插入图片描述

java虚拟机内存

最后我们说一下java虚拟机内存是怎么回事

  1. JVM(java虚拟机)主要包括三块内存空间,分别是:栈内存、堆内存、方法区内存。(上面的内存图都给你画出来了)

  2. 堆内存和方法区内存各有一个,而一个线程一个栈内存。

  3. 方法调用的时候,该方法所需要的内存空间在栈内存中分配,称为压栈。方法执行结束之后,该方法所属的内存空间释放,称为出栈。

  4. 栈中主要存储的是方法体当中的局部变量。

  5. 方法的代码片段以及整个类的代码片段都被存储到方法区内存当中,在类加载的时候这些代码会载入。

  6. 在程序执行过程中使用new运算符创建的java对象,存储在堆内存当中,对象内部有实例变量,所以实例变量存储在堆内存当中。

  7. 变量分类:
    局部变量【方法体中声明】

    成员变量【方法体外声明】:分为实例变量,静态变量(有无static修饰)

  8. 静态变量存储在方法区内存

  9. 三块内存当中变化最频繁的是栈内存,最先有数据的是方法区内存,垃圾回收器主要针对的是堆内存。

  10. 垃圾回收器【自动垃圾回收机制、GC机制】什么时候会考虑将某个java对象得内存回收呢?
    答:当堆内存当中的java对象成为垃圾数据的时候,会被垃圾回收器回收。

  11. 什么时候堆内存中的java对象会变成垃圾呢?
    答:没有更多的引用指向它的时候。
    这个对象无法被访问,因为访问对象只能通过引用的方式。

结语

结语:感觉这次博客写的有点乱,读者看起来可能会觉得累吧,最后面的关于java虚拟机的东西我觉得值得一看呢,不过我也就一个小白。如果有错误请指出来鸭,加油鸭!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值