误区不知道从哪里听来的==比较的是地址和值,equals比较的是值。这是大错特错的。
==
首先 ==在比较基本数据类型的时候比较的是值,而比较对象的时候比较的是两个对象的地址。
- 数组属于对象,所以在比较数组的时候是以比较对象得方式
int x = 10;
int y = 10;
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(x == y); // 输出true
System.out.println(str1 == str2); // 输出false
equals
- equals()方法存在于Object类中
- equals()方法可以被重写
- 大多数Java的数据封装都重写了equals()方法
- 查看源码可以得知equals()底层的实现依赖的其实是==
==和equals()
首先==和equals()最大的区别就是一个是运算符一个是方法,在Java中二者比较的都是物理地址,而不是值的比较。
Student student1 = new Student();
Student student2 = new Student();
System.out.println(student1.equals(student2));//false
System.out.println(student1 == student2);//false
不论是用的是哪一种方法 , 最终的结果显示的都是false,大家不妨可以试一下。为什么呢?就是因为他们比较的不是对象中字段的值或者说本身对象的值,而比较的是物理地址。
所以在没有重写equals()方法的类中,使用equals和使用==其实是一样的,但是在多数Java的类中,大多都重写了equals()方法,并且大多数一般都是指定它去比较两个对象的值。
这里我们自定义的Student类并没有重写String方法,所以输出结果是false。
在重写了equals()方法以后,指定让它比较值的大小,所以输出为true。
特殊的关键字String
String简介
JDK1.8中JVM把String常量池移入了堆中,同时取消了“永久代”,改用元空间代替(Metaspace)
java中对String对象特殊对待,所以在heap区域分成了两块,一块是字符串常量池(String constant pool),用于存储java字符串常量对象,另一块用于存储普通对象及字符串对象。
下面是String的创建方式:
public static void main(String[] args) {
String a = "abc"; //第一种
String b=new String("abc"); //第二种
String c = "abc";
System.out.println(a == b);//false
System.out.println(a == c);//true
}
- 对于第一种,此创建方法会在Java constant pool中创建对象。JVM首先会在常量池中寻找是否存在"abc"常量,如果没有则创建该常量,并且将此常量的引用返回给String a;如果已有"abc" 常量,则直接返回String constant pool 中“abc” 的引用给String a。
- 对于第二种,jvm会直接在非String constant pool 中创建字符串对象,然后把该对象引用返回给String b,并且不会把"abc” 加入到String constant pool中。new就是在堆中创建一个新的String对象,不管"abc"在内存中是否存在,都会在堆中开辟新空间。
- 虽然new String()方法并不会把"abc” 加入到String constant pool中,但是可以手动调用String.intern(),将new 出来的字符串对象加入到String constant pool中。
String s1 = new String("abc");
String s2 = "abc";
System.out.println(s1 == s2); //false
System.out.println(s1.intern() == s2); //true
String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);
所以在这个方法中,两个方法都是true,因为当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象"abc",第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。