那些java中的 == 跟 equals的理解

==  and  equals的比较

一.基本数据类型中比较
java中八个基本数据类型都是可以用 == 判断的,只要不超过该数据类型的范围,只要数值相同 用 == 判断返回的结果都是true

int a = 222;
int b = 222;

System.out.println(a == b); //true

double a3 = 22222222.222;
double b3 = 22222222.222;
System.out.println(a3 == b3); //true
System.out.println(15.5d == 15.5f); //true

原因是因为基本数据类型的值是存储在内存的栈中的,他的引用(相当于c中的指针,就是地址值)也是存在栈中的,当存入一个数据的时候会先在栈中寻找看先前是否已经存在了相同的数据,如果存在了就只会创建一个引用指向那个数据的内存地址,所以只是创建了一个引用而引用都是指向同一个地址所以使用 == 判断的时候是true的。

二.包装数据类型的比较(面试的坑好多在这里)

所谓的包装数据类型就是基本数据类型的封装成了对象,当时他存储的方式就变化了很多,来看一个面试的题
Integer a2 = 127;
Integer b2 = 127;

System.out.println(a2 == b2);  //true

Integer a1 = 222;// = Integer a22 = new Integer(127);
Integer b1 = 222;
System.out.println(a1.equals(b1)); //true
System.out.println(a1 == a2);  //false
       
很多人就坑在了这个上面,为什么222的时候就不相等了呢,其实看一下Integer的官方源码就可以发现问题所在,下面把Integer的源码摆出来

   *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.


这句话的意思就是java中缓冲了-128-127的值在常量池中,当你创建这个范围类的Integer对象时,他是不会新创建对象的,而是创建一个引用指向那个系统的地方,所以当你创建两个在这个范围的值的时候,他们的引用的指向是一样的, 所以 == 返回的true。但那个值超过了这个范围是java中没有缓冲这些数据,只能新创建对象,当对象是new 出来的时候存储的位置都是堆中,而栈中存储的只能是基本数据类型的数据和引用,所以包装数据类型创建的对象是放在堆里面,并且在栈中创建一个引用指向那个堆中的地址,但是堆中创建对象时是不会去检索是否存在,而是新创建一个对象跟引用所以两个 == 时返回的时 false。


三.引用数据类型的比较(坑爹的String)
引用数据类型:数组,接口,类。
之所以叫引用数据类型就是因为每次创建的时候都需要新创建一个引用,这个分类的对象都是通过new 来创建的(除了String这个奇葩).上面说过当对象是new出来的时候数据储存的位置是在堆中的。

int[] a5 = new int[5];
int[] b5= new int[5];
System.out.println(a5 == b5);  //false

每次创建的时候都是在堆中新建一个对象,然后在栈中创建一个引用指向堆中。所以他的== 是返回false;

这中间有个奇葩String
上代码
String a12 = "123";
String b12 = "123";
System.out.println(a12 == b12);  //true

String a13 = new String("123");
String b13 = new String("123");
System.out.println(a13 == b13); //false

这是为何呢???

    其实是因为java的常量池中有一个字符数据池,当你以 = “” 字符串的形式创建的时候,
   他是会在常量池中创建一个对象,而为什么会相等呢?
   这是因为java往常量池添加数据时会先检查常量池中有没有先前就存在这样的对象,
   如果存在则只创建一个引用指向改常量池的地址,所有两个就相等了
   所有那个经常问到的面试题  String a = ""; 会创建几次答案就出来了,结果是一次或者两次 ,因为有可能常量池中已经存在这个字符串了,那就只创    建一个引用对象,没有就在常量池中创建一个字符串对象,再在栈中创建一个引用指向这个地址。

四.最后讲一下equals方法
equals方法比较对象时,是通过比较对象的equals方法的返回值是否为true,还有hashcode方法返回是否是0.
所以自己定义的类要比较时就得重写object的equals方法和hashcode方法,才能通过equals方法进行比较。

csdn上的第一篇文章,写的不怎么样可能有些地方理解的不好,望海涵,也希望各位大神多多指导,小生定当顶礼膜拜。
----Android小菜鸟   pmj
qq:1037801608(欢迎指导,共同学习)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值