Java中equals与==的区别
基础知识在对于我们的工作学习时,是非常重要的。
判断两个对象是否相等有两种方式:一种是利用 == 运算符,另一种是利用equals方法。
基本数据类型
- int 整型
- short 短整型
- long 长整型
- byte 字节型
- char 字符型
- float 单精度浮点型
- double 双精度浮点型
- boolean 布尔型
引用数据类型
- 类
- 接口类型
- 数组类型
- 枚举类型
- 注解类型
1.基本数据类型的比较
对于基本数据类型来说,只能通过“==”来进行比较两个变量的value值是否相同,这里举几个例子:
int i1=10;
int i2=10;
System.out.println(i1==i2); //true
char test='a';
char test1='a';
System.out.println(test==test1); //true
2.基本数据类型与引用类型对象的比较
当基本数据类型与引用类型比较时,“==”和equals两种方式都可以使用,且都是按照值比较
int i1=130;
Integer i2=new Integer(130);
System.out.println(i2.equals(i1)); //true
char test='a';
Character test1=new Character('a');
System.out.println(test==test1); //true
3.引用类型对象与引用类型对象的比较(直接赋值)
下面六种包装类缓存池有默认内容:
包装类 | 缓存池范围 |
---|---|
Byte | -128~127 |
Short | -128~127 |
Integer | -128~127 |
Long | -128~127 |
Character | '\u0000'~'\u007F' |
boolean | true和false |
当这六种包装类直接赋值缓存池范围内的值时,“==”指向的地址相同,否则地址不同,而equals方式由于各个包装类都重写了equals方法,判断值是否相同
例:
Integer i1 =300;
Integer i2=300;
System.out.println(i2==i1); //false
System.out.println(i2.equals(i1)); //true
i1=12;
i2=12;
System.out.println(i1==i2); //true
Character test='a';
Character test1=new Character('a');
System.out.println(test==test1); //false
System.out.println(test1.equals(test)); //true
Double d1=12.0;
Double d2=12.0;
System.out.println(d1==d2); //false
当直接将缓存池中的常量值赋给引用型对象时,对象从栈创建之后,直接引用的是在堆中常量池中值的地址,但是如果直接赋值的数据不在缓存池的范围内,将在堆中new 一个对象,同时在常量池中创建这个值,堆中的对象将指向这个常量池中的值。
Double和Float缓存池没有默认值
4.引用类型对象与引用类型对象的比较(new 对象)
当使用new对象时,将在堆创建一个对象,对象名指向这个对象,对象指向常量池中的值的地址。如果常量池存在这个值,将直接指向,否则将要创建一个常量值并指向。由于对象名指向的是对象的地址,所以“==”比较地址不同,重写的equals方法比较的是值是否相同。
Integer i1 =new Integer(300);
Integer i2=new Integer(300);
System.out.println(i2==i1); //false
System.out.println(i2.equals(i1)); //true
i1=new Integer(12);
i2=new Integer(12);
System.out.println(i1==i2); //false
5.String的比较
在比较String类时,“==”比较的是地址,equals方法比较的是值是否相同,给大家看一下重写的String的equals源码:
public boolean equals(Object anObject) {
if (this == anObject) { //首先判断地址是否相同
return true;
}
if (anObject instanceof String) { //地址不同,判断值是否相同
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
例:
String s1="123";
String s2=new String ("123");
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2)); //true
String s3="123";
System.out.println(s1==s3); //true
new和直接赋值的区别:
直接赋值首先在常量池里边搜索是否存在,如果不存在的话,将创建一个常量值,并直接指向。
new的话,首先在堆中创建一个对象,对象在指向一个常量池的值,如果不存在,也是创建常量值,再将对象指向常量值。如果将常量直接给对象名,则对象名直接指向常量池的常量,而不是指向堆中的对象,对象在指向常量池的常量。
String s1="123";
String s2=new String ("123");
System.out.println(s1==s2); //false
System.out.println(s1.equals(s2)); //true
s2="123";
System.out.println(s1==s2); //true
5.Object的比较
如果自己创建的类,没有继承其他包装类,则在比较对象时,“==”和equals方法相同都是比较地址是否相同,Object的源码:
public boolean equals(Object obj) {
return (this == obj); //比较地址是否相同
}
例:
person person = new person();
person person1 = new person();
System.out.println(person1==person); //false
System.out.println(person1.equals(person)); //false