==和equals()都可以用来判断两个变量是否相等
==:
如果判断的两个变量是基本类型并且是数值类型 则只要两个变量的值相等 == 返回true
如果判断的两个变量是引用类型 则如果它们指向的是同一个对象 == 返回true
package com.tony.app;
public class EqualsDemo {
public static void main(String[] args) {
int a = 88;
int b = 88;
System.out.println(a == b); // true
String str1 = new String("tony");
String str2 = new String("tony");
System.out.println(str1 == str2); // false
// 都是数值类型 但不必类型完全相等 只要隐性自动转化便可
int c = 65;
float d = 65.0f;
char e = 'A';
System.out.println(c == d); // true
System.out.println(c == e); // true
System.out.println(d == e); // true
// == 不能比较类型上没有父子关系的对象
// Incompatible operand types String and EqualsDemo
// System.out.println("tony" == new EqualsDemo());
/**
* str3和str4都是String类型 str3是直接量 JVM会使用常量池来管理直接量和可以在编译时期就能计算出来的字符串值 new
* String("tony"):首先"tony"的直接量 用这个直接量构造出一个对象 str4引用这个新的对象
* new String("tony")共产生了两个对象
* 1.new String()
* 2."tony"
*/
String str3 = "tony";
String str4 = new String("tony");
System.out.println(str3 == str4); // false
// 常量池
String str5 = "文心tony";
String str6 = "文心";
String str7 = "tony";
/**
* str8的值在编译时期就能确定下来 直接引用常量池中的"文心tony" 也就是说str5和str8同时指向常量池中的"文心tony"
*/
String str8 = "文心" + "tony";
String str9 = "文" + "心" + "tony"; // 同str8 此时str5,str8,str9同时指向"文心tony"
String str10 = str6 + str7; // 编译时不能确定值 不会去引用常量池中的字符串
String str11 = new String("文心tony");
System.out.println(str5==str8); // true
System.out.println(str5==str9); // true
System.out.println(str8==str9); // true
System.out.println(str5==str10); // false
System.out.println(str5==str11); // false
/**
* 何为常量池:
* 常量池在java用于保存在编译期已确定的 已编译的class文件中的一份数据
* 它包括了关于类 方法 接口等中的常量 也包括字符串常量 如String s = "java"这种声明方式
* 当然也可扩充 执行器产生的常量也会放入常量池 故认为常量池是JVM的一块特殊的内存空间
*/
}
}
equals:
它是Object类中的一个方法 equals方法不能作用于基本数据类型的变量
查看源码可以发现 Object类中的equals()方法还是使用==比较两个对象
所以在没有重写equals()方法的类中 调用equals()方法其实和使用==号的效果一样 也是比较的地址值
但是Java提供的所有类中 绝大多数类都重写了equals()方法(如String类) 重写后的equals()方法一般都是比较两个对象的值
String类重写了equals()方法 只要两个字符串对象包含的字符序列相同 返回的是true
当然也可以自定义比较方法 只要重写equals()实现即可
1.Tony类实例同任何对象都相同
package com.tony.app;
public class Tony {
// 重写equals()方法
@Override
public boolean equals(Object obj) {
// Tony实例同任何对象都相等(just for test)
return true;
}
}
package com.tony.app;
public class EqualsDemo {
public static void main(String[] args) {
System.out.println(new Tony().equals("tony")); // true
System.out.println(new Tony().equals("文心")); // true
}
}
2.Tony类实例 name和age相同 才表示相同
package com.tony.app;
public class Tony {
private String name;
private int age;
public Tony(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 重写equals()方法
@Override
public boolean equals(Object obj) {
// 对象引用的地址相同 表示指向同一个对象
if (this == obj) {
return true;
}
// 比较的对象不能为空 并且是Tony的实例
if (obj != null && obj.getClass() == Tony.class) {
Tony tony = (Tony) obj;
if(this.getName().equals(tony.getName()) && this.getAge()==tony.getAge()) {
// 姓名和年龄相同才表示实例相同
return true;
}
}
return false;
}
}
package com.tony.app;
public class EqualsDemo {
public static void main(String[] args) {
Tony tony1 = new Tony("tony",18);
Tony tony2 = new Tony("tony",28);
Tony tony3 = new Tony("文心",18);
Tony tony4 = new Tony("tony",18);
System.out.println("tony1和tony2相等:" + tony1.equals(tony2));
System.out.println("tony1和tony3相等:" + tony1.equals(tony3));
System.out.println("tony1和tony4相等:" + tony1.equals(tony4));
System.out.println("tony1和tony1相等:" + tony1.equals(tony1));
}
}
结果输出:
tony1和tony2相等:false
tony1和tony3相等:false
tony1和tony4相等:true
tony1和tony1相等:true
![](https://i-blog.csdnimg.cn/blog_migrate/2251dbc77028ab9644e3ad06c16228d4.png)