为下面这段Java代码补充类图_Java学习笔记系列【二】类与对象的进一步探索!...

上次我们讲到创建对象。这次我们深入来研究下对象在内存中的关系。这些对象在内存中的究竟发生哪些操作了?

我们先来看下上次的这个代码。

Public class Puppy{

public Puppy(String name){

System.out.println("它的名字是:"+name);

}

public static void main(String[] args){

//创建一个Puppy对象。

Puppy myPuppy = new Puppy("tommy");

}

}

重点:Puppy myPuppy = new Puppy(“tommy”);

在解释之前,我们先补充下。因为我们介绍的类和对象是引用数据类型。

而引用数据类型必然存在栈内存-----堆内存的引用关系。

见代码哦亲:

代码:

Puppy myPuppy //实例化myPuppy,在栈内存中创建myPuppy对象

new Puppy("tommy"); //初始化Puppy,把堆内存中的name赋值为tommy

一图值千金,下面我们来看张图吧。

![图片描述][1]

首先初始化Puppy,在堆内存中把name赋值为tommy.

在实例化myPuppy,在栈内存中创建myPuppy对象,并指向堆内存。

我们在来看个代码:

class Person{ //定义个Person类。(人.)

String name; //定义name属性。

int age; //定义age属性。

public void tell(){ //定义tell()行为。方法。

System.out.println("姓名:"+name+"年龄:"+age);

}

};

public class Demo{

public static void main(String args[]){

Person per=new Person(); //创建并实例化对象per.

}

}

其中Person的类图是这样的。

![图片描述][2]

这里来介绍下类图的概念:

类图包含3个组成部分。第1个是Java中定义的类名。第2个是属性。第3个是该类提供的方法。(用UML图来表示的话,第1层为类名,第2层为类的属性,第3层为类的方法。属性和方法之前可以添加一个修饰符。"+"号表示具有公共可见性 "-"号:私有可见性。"#"号:受保护的可见性 "_"号:静态的)

看了上面的类图概念是不是有晕了?码段代码来清醒下。

public class Employee{ //定义雇员类。

private int empID; //雇员ID.

public double calcSalary(){ //calcSalary()方法。(薪水)

}

}

类图

![图片描述][3]

第1层:为java中的Employee类名。

第2层:为Employee类中empID属性,该属性为公共。且是int型的。

第3层:为Employee类中calcSelary();行为,该行为为公共。且是double型

其实上面的代码 Person per =new Person();还可以这样划分。

Person per=null; //声明对象。(赋初为空null)

per=new Person(); //实例化对象。(指向堆内存。)

为了理解,我们还是在码几个程序。

class Person{

String name;

int age;

public void tell(){

System.out.println("姓名:"+name+"年龄:"+age);

}

}

public class Demo01{

public static void main(String args[]){

Person per1=null; //声明对象(赋初值。)

Person per2=null; //声明对象(赋初值。)

per1=new Person(); //实例化对象per1(指向对内存Person)

per2=new Person(); //实例化对象per2.

per1.name="张三"; //改变per1指向的堆内存中name的值

per1.age=30; //改变per1指向的堆内存中age的值.

per2.name="李四"; //改变per2指向的堆内存中name的值

per2.age="33"; //改变per2指向的堆内存中age的值

System.out.println("per1对象中的内容为:");

per1.tell();

System.out.println("per2对象中的内存为:");

per2.tell();

}

}

>代码**运行效果**:

![图片描述][4]

代码在**内存中表现**:

![图片描述][5]

**代码逻辑:**这个per1=new Person();和per2=new Person();是分别指向不同的堆内存空间。然后分别更改per1和per2里指向的堆内存空间里的name和age的值,在输出。

> **所谓的引用数据类型,实际上传递的就是堆内存的使用权,可以同时为一个堆内存空间定义多个栈内存的引用操作。**

来看段代码吧,亲。。

class Person{ //定义Person类。

String name; //定义名字属性。

int age; //定义年龄属性。

public void tell(){ //定义tell行为。

System.out.println("姓名为: "+name+"年龄为: "+age);

}

};

public class Demo02{

public static void main(String args[]){

Person per1 =null; //声明per1对象(赋初值)

Person per2 =null; //声明per2对象(赋初值)

per1 = new Person(); //只实例化per1对象。

per2=per1; //把per1的堆内存空间所有权分配给per2.

per1.name="张三"; //设置per1中name属性内容。

per1.age=30; //设置per1中age属性内容。

per2.name="李四"; //设置per2中name属性内容。

per2.age=33; //设置per2中age属性内容。

System.out.println("per1中对象的内容为:");

per1.tell(); //通过per1对象调用tell()方法。

System.out.println("per2中对象的内容为:");

per2.tell(); //通过per2对象调用tell()方法。

}

}

> **代码运行效果:**

![图片描述][6]

**代码逻辑:**首先声明per1和per对象并赋初值,实例化per1对象,并把per1的堆内存空间所有权分配给per2。也就是说per1和per2指向同一个堆内存空间。首先通过per1变量,更改name="张三",age=30。在通过per2变量,更改为name="李四",age=33。**(覆盖原来的值)**在输出。。。

这段代码在内存中表现形式为:

![图片描述][7]

![图片描述][8]

因为per1和per2都是指向同一个堆内存空间。通过per2来改变name及age的属性值。就等同于per1来改变的。

*我们在来看一道引用传递的例子。*

class Person{ //定义个Person类.(人.)

String name; //定义name属性。

int age; //定义age属性。

public void tell(){

System.out.println("姓名:"+name+"年龄:"+age);

}

}

public class Demo03{

public static void main(String[] args){

Person per1=null; //声明per1对象在栈内存,并赋空值

Person per2=null;//声明per2对象在栈内存,并赋空值

per1=new Person();//实例化per1对象,指向对应的堆内存

per2=new Person();//实例化per2对象,指向对应的堆内存

per1.name="张三"; //改变per1所指向的堆内存中name值。

per1.age=30; //改变per1所指向的堆内存中的age值。

per2.name="李四";

per2.age=33;

per2=per1; //per2指向per1的堆内存空间。之前per2所指向的堆内存空间为垃圾。

System.out.println("per1对象的内容:");

per1.tell();

System.out.println("per2对象的内容:");

per2.tell();

}

}

代码逻辑:我们首先声明per1和per2对象,并实例化per1和per2。指向对应的堆内存空间。

![图片描述][9]

然后我们给per1所指向的堆内存空间中name赋值为”张三”,age为30。

给per2所指向的堆内存空间中name赋值为”李四”,age为33。

![图片描述][10]

但是后来per2有重新指向per1所指向的堆内存空间。(之前per2所指向的堆内存空间被jvm视为垃圾空间。)

![图片描述][11]

在执行“System.out.println(“”).....per1.tell();”

”System.out.println(“”)........per2.tell();”

分别调用tell();方法。输出内容。

代码运行效果:

![图片描述][12]

上面的代码因为per2改变了指向,所以其原本的内存空间就没有任何栈的引用。则这样的内存就被称为垃圾空间,等待着垃圾收集机制GC的回收。

我们了解这块内容java中内存是如何划分的,以后不管多复杂的程序都可以按照这个内存划分图来分析滴,亲。

**亲,这次我们就聊的这了,我们下期再见了。荆轲刺秦王。**

> 感谢老铁们再次把宝贵的时间浪费在我的文章上。哀心的感谢各位老铁们。谢谢。。

这里我推荐一个在线UML制图工具。[ProcessOn][13]挺好用的。老铁们有兴趣的可以去逛逛。

[1]: http://img1.sycdn.imooc.com/59f212e000014b1705960318.png

[2]: http://img1.sycdn.imooc.com/59f217b50001234602030155.png

[3]: http://img1.sycdn.imooc.com/59f2c7900001e39e03010126.png

[4]: http://img1.sycdn.imooc.com/59f34d720001e00404030150.png

[5]: http://img1.sycdn.imooc.com/59f34da9000119ab07420323.png

[6]: http://img1.sycdn.imooc.com/59f359e60001a59202780170.png

[7]: http://img1.sycdn.imooc.com/59f35fbe00015dfb06150194.png

[8]: http://img1.sycdn.imooc.com/59f35fed0001a9bf06330185.png

[9]: http://img1.sycdn.imooc.com/59f367650001d04c04910231.png

[10]: http://img1.sycdn.imooc.com/59f3680e00012dcb04520145.png

[11]: http://img1.sycdn.imooc.com/59f3692800018c9604320163.png

[12]: http://img1.sycdn.imooc.com/59f369c70001e05402970165.png

[13]: https://www.processon.com/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值