黑马程序员——面向对象9:对象的初始化&方法的调用

本文详细解析了Java中对象的创建过程及其初始化步骤,包括类加载、成员变量初始化等,并介绍了对象方法调用的具体流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

------- android培训java培训、期待与您交流! ----------

这一篇我们来详细描述一下,创建一个对象和对象调用方法时,在内存中都发生了什么,也算是对之前学习的内容的一个总结。

代码1:

class Person
{
	private String name;
	private int age;
	private static String country = "CN";
	{
		System.out.println("name = "+this.name+",age = "+this.age);
	}
 
	Person(String name, int age)
	{
		this.name  = name;
		this.age = age;
	}
 
	public void setName(String name)
	{
		this.name = name;
	}
	public void speak()
	{
		System.out.println("name="+this.name+",age="+this.age);
	}
	public static void showCountry()
	{
		System.out.println("country = "+country);
	}
}<strong style="text-decoration: underline;">
</strong>class PersonDemo
{
	public static void main(String[] args)
	{
		Person p = new Person("Tom", 33);
		p.setName(“Jack”);
	}
}
1. 对象的初始化过程

当主函数运行到“Person p = new Person()”语句时,

第一步:在栈内存中为主函数开辟一块空间,并先执行赋值符左侧的语句,在栈内存中创建一个Person类类型变量p;

第二步:在继续执行右侧的语句之前,将Person类加载进内存,更具体说,就是当执行“new Person()”时,虚拟机将“Person.class”(字节码)文件加载进内存;

第三步,加载Person类的同时,在方法区中为该类开辟一块空间(所谓开辟,其实就是将这片内存区域清零,也就是默认初始化,下同),与此同时在此创建这个类的所有静态成员和方法(注意,静态方法和非静态方法是分在两个空间存储的),然后对静态成员变量(该例中为country)进行默认初始化(引用数据类型变量赋null,boolean型变量赋false,其他基本数据类型变量赋0,下同),最后进行显示初始化;

第四步:如果有的话执行静态代码块;

第五步:在堆内存为Person对象开辟了一块空间,并为这个空间分配一个地址值,接着在此创建该对象所有的非静态成员变量(该例中为name和age)并进行默认初始化,然后进行显示初始化;

第六步:如果有的话执行对象的构造代码块;

第七步:执行相对应的构造函数;

第八步:最后将上述内存的地址值赋给栈内存中的变量p,p就指向了堆内存中的Person对象。

2. 方法的调用

当主函数运行“p.setName(“Jack”)”语句时,在栈内存为setName方法开辟一块空间,并在其内部创建局部变量name,而且这块内存空间一开辟就存在了对本类对象的引用——this。实际上这个this的值就是对象在堆内存中的地址值,那么this也就指向了堆内存中调用setName方法的本类对象。在调用setName方法的同时将字符串“Jack”作为实际参数传入setName方法中,这个值接着赋给了方法中的局部变量name,然后通过赋值语句将“Jack”赋给了堆内存中Person对象(this关键字的作用)的成员变量——name。

以上就是非静态方法的调用过程在内存中的体现。如果是调用静态方法,比如showCountry方法,那么与调用非静态方法的相同点是:都要在栈内存为方法开辟一块空间;区别在于:因为没有对象产生,所以不涉及堆内存,也不需要this关键字的指向作用;只是栈内存与方法区中的变量之间的互相访问。


小知识点1:

大家都知道静态方法只能调用静态方法,比如下述代码,

代码2:

class Demo
{
	public static void method()
	{
		System.out.println(“method run”);
	}
	public static void function()
	{
		System.out.println(“function run”);
		method();
	}
}
上述代码中,function方法内部调用了method方法,这就和非静态方法互相调用相同时放方法名前面省略了this一样,静态方法相互调用时方法名前省略了类名,所以完整写法是“Person.method()”。这同样也适用于静态成员变量。实际上,大家要记住,所有方法(无论是否静态)的执行都是需要调用者,静态方法的调用者是类,非静态方法是对象,主函数是虚拟机。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值