A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 徘徊消逝中 于 2014-6-5 23:19 编辑

本来是想问这个问题的:一个类A的实例a以参数形式传递到另一个类B中,做为B的一个属性,那么如果类B实例化多个对象,且该属性都以类A的同一个实例a为参数,那么这许多的B类的实例是不是操作的是同一个属性资源,还是分别在B类的每一个实例中都重新创建新的属性。说起来比较拗口。
本来想问问大家了,后来自己测试了,不知道大家有没有其他的看法,或者更好的做法:
本测试不要计较逻辑,只是个简单的技术点的测试:
  1. package blog5;

  2. public class test {
  3.         public static void main(String[] args) {
  4.                 Person p = new Person("张三",20);
  5.                
  6.                 Classrom classromA = new Classrom(p, "李老师");
  7.                 Classrom classromB = new Classrom(p, "张老师");
  8.                 //输出原来的AB教室中学生情况
  9.                 System.out.println(classromA.getPerson().toString());
  10.                 System.out.println(classromB.getPerson().toString());
  11.                 //改变A教室中学生年龄
  12.                 classromA.getPerson().setAge(100);
  13.                 //查看B教室中学生年龄
  14.                 System.out.println(classromB.getPerson().toString());
  15.                 // 结果:B教室中学生年龄编程了100,所以AB教室中的学生对象是同一个对象p
  16.         }

  17. }

  18. class Classrom{
  19.         
  20.         private Person p;
  21.         private String teacher;
  22.         
  23.         public Classrom(Person p,String teacher) {
  24.                 this.p = p;
  25.                 this.teacher = teacher;
  26.         }

  27.         public Person getPerson() {
  28.                 return this.p;
  29.         }
  30. }
  31. class Person{
  32.         private String name;
  33.         private int age;
  34.         
  35.         public Person(String name,int age) {
  36.                 this.name = name;
  37.                 this.age = age;
  38.         }
  39.         
  40.         public String getName() {
  41.                 return name;
  42.         }
  43.         
  44.         public int getAge() {
  45.                 return age;
  46.         }
  47.         
  48.         public void setAge(int age) {
  49.                 this.age = age;
  50.         }
  51.         
  52.         @Override
  53.         public String toString() {
  54.                 return "name:" + name + " ,age:" + age;
  55.         }
  56. }
复制代码



评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

9 个回复

倒序浏览
学习一下
回复 使用道具 举报
好像用的是同一个对象p
回复 使用道具 举报
Hi天天向上 发表于 2014-6-2 09:51
好像用的是同一个对象p

嗯,以测试结果来说,是这样的,这一点以前没有特别注意
回复 使用道具 举报
徘徊消逝中 发表于 2014-6-2 11:44
嗯,以测试结果来说,是这样的,这一点以前没有特别注意

学习了.
回复 使用道具 举报
肯定是同一资源啊 你就只new了一个Person对象出来,并且p本身就指向了Person对象的地址,你在两个Classrom中都是放的p啊

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

回复 使用道具 举报
Blackay 发表于 2014-6-2 14:53
肯定是同一资源啊 你就只new了一个Person对象出来,并且p本身就指向了Person对象的地址,你在两个Classrom ...

进一步问一下你,你说Classrom类的每个实例是不是要为它的属性private person p开辟内存空间,那么这个空间存放的是一个person的引用,还是一个完整的person内容的堆内存。
回复 使用道具 举报
徘徊消逝中 发表于 2014-6-2 23:03
进一步问一下你,你说Classrom类的每个实例是不是要为它的属性private person p开辟内存空间,那么这个 ...

引用,当你实例化之后,这个引用就指向了你构造函数里面传进来的对象 并且同时为其开辟一块堆内存,里面存放的就是Person类的一些变量和方法
回复 使用道具 举报
Blackay 发表于 2014-6-3 08:14
引用,当你实例化之后,这个引用就指向了你构造函数里面传进来的对象 并且同时为其开辟一块堆内存,里面 ...

后面半句不是特别理解:既然引用已经指向了构造函数里传进来的对象(此对象已经实例化存在了),那么还会需要开辟堆内存,去存放Person类的变量和方法吗?直接用引用去调用已经存在的资源不就够了么?你这种说法里面,引用指向了Person类对象,但是又开辟了一个Person类对象的堆内存,那么这块内存资源谁来用?如果Classrom中修改Person属性,是修改引用指向的地址,还是这个新开辟的堆内存呢?

不好意思,我比较啰嗦,其实问题也就这一个,只是一直对址传递和值传递不是很了解,希望和你继续讨论下
回复 使用道具 举报
徘徊消逝中 发表于 2014-6-3 11:36
后面半句不是特别理解:既然引用已经指向了构造函数里传进来的对象(此对象已经实例化存在了),那么还会 ...

。。。。。 你传进来的这个形参是一个对象引用对吧 对象的实例化就是开辟内存空间啊 你不开辟内存怎么去存放方法和变量???这块资源就是程序来用啊 为什么要单独开辟? 因为这是另一个类的对象啊 肯定要另外开辟啊 不然你以后不用了 我的垃圾回收机制就可以回收啊,还有你说修改属性怎么可能修改地址,引用你有了,通过这个引用就指向了对象所在内存啊,这样子就相当于在类中修改了啊 ,内存开辟了,地址就固定了,不能修改了,只能多个指向或者单独指向,这个是计算机自己设定的,外部不能改变的。感觉你对内存分配这一块理解的有点问题 可以去多看看马士兵的视频。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马