之前就买了java编程思想,然后自己想来看看里面的一些东西,果然书挺好的,比着里面的代码写了写,有一些感受在这里展示一下。
对象赋值
首先让我们来看代码
public class New1 {
public static void main(String[] args) {
A a=new A();
A a1=new A();
a.a=10;
a1.a=100;
System.out.println(a.a+""+a1.a);
a=a1;
System.out.println(a.a+""+a1.a);
a.a=1000;
System.out.println(a.a+""+a1.a);
}
}
class A{
Integer a;
}
之前也是做过这种题,我们首先来分析一下。
- 首先是A类中有一个Integer a的属性,然后我们首先在main中,先去new两个A类的对象,分别是对象a,a1,然后分别两个对象的a属性赋值,a对象a属性是10,a1对象a属性是100,然后在这里第一次输出a.a和a1.a,这里毋庸置疑,肯定是10和100.
- 然后我们进行第二次赋值,将a1指向a,然后再次输出a.a和a1.a,结果也是毋庸置疑,也是10和100。
- 而第三次我们这里要注意一个问题我们在这里将对象a的属性a赋值为1000,然后再输出a.a和a1.a,答案是1000,1000.
我们来稍微的分析一下。
首先对象分为两种,一种是基本数据类型,一种是引用数据类型也是包装型类型,基本数据类型是8中分别是byte,short,int,long,char,boolean,float,double,除了这八种以外所有都是引用型数据。
然后因为对象的不同所以他们存储形式也是不同的这里首先我要借鉴一下深入理解jvm虚拟机这本书里一些话,首先这里涉及到java的内存结构,java之所以能够运行是因为有jvm存在,java内存结构中我们这里使用的是Java虚拟机栈(Java Virtual Machine Stacks)
和Java堆(Java Heap)
。
- 从基本数据类型开始,例如我们int a=10;他就会去寻找一个int类型10在栈中,如果没有就会在内存中新建一个10,如果我们还有int b=10;那他就会让b直接指向10。
- 然后是引用数据类型,主要是由两部分组成,对象名称是在栈中的,但是对象的具体是存在堆中,这里还有堆和栈细微区别,在栈中类型大小是在编译期就已经被确定了的,而堆中就不需要被确定大小这一点,当然这个是因为栈的大小是很小的,但是栈的速度也是稍微快的,当然如果你非要说最快,当然是放在缓存cache里面,有一级缓存二级缓存,三级缓存,基本上缓存调用的速度越快,当然这都是题外话,后面有时间我们可以专门就这些基础课完成一篇博客。
我们说回正题,a=a1;我们将a1的指向指定了a,又因为a是一个引用型对象,所以说以后的a的变化a1也会发生变化,我们如果想要避免这个问题我们可以a.a=a1.a;就可以避免这个问题,在这里的a属性具体是基本型还是引用型没有关系,就像是指针虽然说Java中没有指针的这个概念,但是我们可以想象。
在这里我们A类的对象a和A类a1中的属性a,就像是指针,在开始的时候对象a和对象a1指向了不同的地址,这里是他存储的地址。还有他们的属性a,也是指向了对象a和对象a1,当我们将一个对象使用=赋值给了另外的一个对象时,他下面的属性和其他的所有的东西都是相同的。
就像是大鱼也就是对象a或者a1,他们的属性a就是他们的孩子,当两条大鱼相等时他们的孩子也是相等的,但是反之不成立。
我们使用一个程序来进行测试一下
public class New3 {
public static void main(String[] args) {
father f1=new father();
father f2=new father();
f1.son.sonson="1";
f2.son.sonson="0";
System.out.println(f1.son.sonson+"------"+f2.son.sonson);
f1=f2;
System.out.println(f1.son.sonson+"------"+f2.son.sonson);
f1.son.sonson="2";
System.out.println(f1.son.sonson+"------"+f2.son.sonson);
System.out.println(f1==f2);
System.out.println(f1.son==f2.son);
System.out.println(f1.son.sonson==f2.son.sonson);
father f3=new father();
father f4=new father();
f3.son.sonson="1";
f4.son.sonson="0";
System.out.println(f3.son.sonson+"------"+f4.son.sonson);
f3.son=f4.son;
System.out.println(f3.son.sonson+"------"+f4.son.sonson);
f3.son.sonson="2";
System.out.println(f3.son.sonson+"------"+f4.son.sonson);
System.out.println(f3.son.sonson==f4.son.sonson);
father f5=new father();
father f6=new father();
f5.son.sonson="1";
f6.son.sonson="0";
System.out.println(f5.son.sonson+"------"+f6.son.sonson);
f5.son.sonson=f6.son.sonson;
System.out.println(f5.son.sonson+"------"+f6.son.sonson);
f5.son.sonson="2";
System.out.println(f5.son.sonson+"------"+f6.son.sonson);
System.out.println(f5==f6);
System.out.println(f5.son==f6.son);
System.out.println(f5.son.sonson==f6.son.sonson);
}
}
class father{
son son=new son();
}
class son{
String sonson;
}
首先呢我们需要去明确一点,就是 = = 指的是两个对象的地址相同,也就是说即使是两个对象参数等数据完全相同,但是只要是都是new出来,两个对象 = = 就不相等。
然后我们来公布一下我们打印的结果。
我们在这里像是做了几条鱼
首先恩,father这个对象就想大鱼,然后是son像是中鱼,sonson属性就像是小鱼,于是只要是大鱼相同,他下面的中鱼和小鱼一定相同内存地址都相同,但是小鱼一样,他们的大鱼和中鱼就不一样。