一、== 运算符
1.1 基本类型的 == 运算
对于基本数据类型来说,== 比较的是值
public class Main {public static void main(String[] args) {int a = 10;int b = 20;int c = 10;System.out.println(a == b); // output: falseSystem.out.println(a == c); // output: true}}
1.2 引用类型的 == 运算
1.2.1 普通对象的 == 运算
public class Book {private String bookName;private String bookAuthor;public Book() {}public String getBookName() {return this.bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getBookAuthor() {return this.bookAuthor;}public void setBookAuthor(String bookAuthor) {this.bookAuthor = bookAuthor;}}
public class Main {public static void main(String[] args) {Book book1 = new Book();book1.setBookName("西游记");book1.setBookAuthor("吴承恩");Book book2 = new Book();book1.setBookName("西游记");book1.setBookAuthor("吴承恩");System.out.println(book1); // output: Book@16b98e56System.out.println(book2); // output: Book@7ef20235System.out.println(book1 == book2); // output: false}}
即使 book1 与 book2 对象的属性值相同,他们 == 的结果还是 false,就是因为内存地址不同。
1.2.2 String 对象的 == 运算
new 方式
String a = new String("yunhu");String b = new String("yunhu");System.out.println(a == b); // output: false
因为 a 和 b 都是 String 的对象引用,即使内容相同,但是指向的是不同的内存地址。
直接赋值方式
String aa = "yunhu";String bb = "yunhu";System.out.println(aa == bb); // output: true
直接赋值,对象存储在常量池中。
虚拟机会在常量池中寻找是否已经有与将要创建的值相同的对象,如果有直接赋值给当前的引用,如果没有,新建一个 String 对象。二、equals()
equals() 只判断对象是否相等,没有重写
equals()函数的话,判断的依据是对象的地址是否相同。2.1 没有重写 equals()
```java Book book1 = new Book(); book1.setBookName(“西游记”); book1.setBookAuthor(“吴承恩”);
Book book2 = new Book(); book2.setBookName(“西游记”); book2.setBookAuthor(“吴承恩”);
System.out.println(book1.equals(book2)); // output: false
判断对象地址,当然不同。<a name="pZ9Pl"></a>### 2.2 重写 equals()这边为了方便,没有重写 `hashCode`方法, 不过不影响理解。```javapublic class Book {private String bookName;private String bookAuthor;public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getBookAuthor() {return bookAuthor;}public void setBookAuthor(String bookAuthor) {this.bookAuthor = bookAuthor;}@Overridepublic boolean equals(Object obj) {if (this == obj) {return true;}// 判断 obj 对象是不是 Book 类的if (!(obj instanceof Book)) {return false;}Book book = (Book)obj;if(book == null) {return false;}if (this.bookName.equals(book.getBookName()) && this.bookAuthor.equals(book.getBookAuthor())) {// 属性值相同,认为是同一个对象return true;}else {return false;}}}
Book book1 = new Book();book1.setBookName("西游记");book1.setBookAuthor("吴承恩");Book book2 = new Book();book2.setBookName("西游记");book2.setBookAuthor("吴承恩");System.out.println(book1.equals(book2)); // output: true
2.3 String 的 equals()
String a = new String("yunhu");String b = new String("yunhu");System.out.println(a.equals(b)); // output: true
想了想,这不对啊,a、b 是对象引用,equals 比较的是地址,这两个地址不同啊,怎么会返回 true。
String 确实是对象,但是它特殊处理了,重写了 equal 函数,变成比较值,而不是内存地址。
String equals 方法的源码:
public boolean equals(Object anObject) {if (this == anObject) {return true;}return (anObject instanceof String aString)&& (!COMPACT_STRINGS || this.coder == aString.coder)&& StringLatin1.equals(value, aString.value);}
再看下 StringLatin1 类的 equals 源码:
@IntrinsicCandidatepublic static boolean equals(byte[] value, byte[] other) {if (value.length == other.length) {for (int i = 0; i < value.length; i++) {if (value[i] != other[i]) {return false;}}return true;}return false;}
循环比较值。
