判断两个变量栈内存中存储的值是否相等,若是相等返回true,若是不相等返回false。数组
有两种形式的比较须要用到比较运算符“==”,一是两个基本数据类型之间的比较,二是两个引用数据类型之间的比较。缓存
1.两个基本数据类型之间的比较:
性能
八大基本数据类型:byte,short,int,long,double,folat,boolean,char,其中占一个字节的是byte和boolean,short和char占两个字节,int,float占四个字节,double和long占8个字节,这八种数据变量中直接存储其值,变量是在栈中存储的。this
所以:“==”比较基本数据类型时,比较的是值。spa
JAVA 基本数据类型建立单个变量是不能够new的,由于new的都是对象。但建立基本数据类型数组时能够new,由于数组是对象。code
int a = 5; int b = 5; int c = 6; System.out.println(a == b); // 5 == 5 System.out.println(a == c); // 5 == 6
建立了是三个基本数据类型的变量,他们在栈中存储的值就是其数值自己,栈中值由低到高依次为a(5)、b(5)、c(6)。所以“a==b”其本质就是“5==5”,返回true;“a==c”其本质就是“5==6”,返回false。对象
所以,运行结果依次为:true false。blog
2.两个引用数据类型之间的比较:
继承
引用数据类型都是对象,通常都是在堆中被建立,变量中存储的是堆中对象的地址引用。内存
所以,“==”比较引用类型时,比较的是地址。
这里要注意两个数据类型,一个是String类型,一个是Integer类型。具体请看案例分析:
String str1 = new String("abc"); // 0x123 String str2 = new String("abc"); // 0x262 String str3 = new String("xyz"); // 0x762
System.out.println(str1 == str2); // 0x123 == 0x262 System.out.println(str1 == str3); // 0x123 == 0x762
用new建立了三个String类型的对象,建立的三个对象都在堆中,所以有不一样的地址引用。三个变量在栈中存储的是三个对象的地址引用,其值各不相同。
所以,运行结果依次为:false false。
String str1 = "abc"; // 0x111 String str2 = "abc"; // 0x111 String str3 = "xyz"; // 0x123 System.out.println(str1 == str2); // 0x111 == 0x111 System.out.println(str1 == str3); // 0x111 == 0x123
直接建立了三个String类型的对象,建立的字符串在字符串常量池中,所以建立已经存在的字符串会直接返回其地址引用。str2在栈中存储的值和str1在栈中存储的值是同样的,都是字符串“abc”在字符串常量池中的地址引用,而str3在栈中存储的是字符串“xyz”在字符串常量池中的地址引用。
所以,运行结果一次为:true false。
Integer s1 = new Integer(100); Integer s2 = new Integer(100); Integer s3 = new Integer(200); System.out.println(s1 == s2); System.out.println(s1 == s3);
用new建立了三个Integer类型的对象,建立的三个对象都在堆中,所以有不一样的地址引用。三个变量在栈中存储的是三个对象的地址引用,其值各不相同。
所以,运行结果依次为:false false。
Integer n1 = 100; Integer n2 = 100; System.out.println(n1 == n2); Integer a1 = new Integer(100); Integer a2 = new Integer(100); System.out.println(a1 == a2); Integer m1 = 300; Integer m2 = 300; System.out.println(m1 == m2); Integer b1 = new Integer(300); Integer b2 = new Integer(300); System.out.println(b1 == b2);
运行结果依次为:true false false false。为何是这样呢?
两个new的好解释,由于是在堆中建立的,每一个对象有惟一的地址,所以会返回false。但第一个和第三个是啥状况呢?
这是由于在Java中为了提升空间和时间性能,Integer类中有一个静态内部类IntegerCache,在IntegerCache类中有一个Integer数组,用以缓存当数值范围为[-128,127]时的Integer对象。因此在自动装箱的过程当中,若是数值在[-128,127]内,会直接返回其地址引用,如果不在才在堆中建立对象。
在Java中许多系统提供的类都定义了equals方法,这个方法用来比较两个独立对象的内容是否相同,而不是比较引用值自己的。自定义方法的定义大体以下(以String类为例):
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String aString = (String)anObject; if (!COMPACT_STRINGS || this.coder == aString.coder) { return StringLatin1.equals(value, aString.value); } } return false; }
可是,若是一个自定义的类中没有定义equals方法,那么它将继承Object类的equals方法,Object类的equals方法定义以下:
public boolean equals(Object obj) { return (this == obj);
}
能够看到,若是一个类中没有显式的定义equals方法,那么equals方法的做用和“==”的做用是同样的,都是比较两个变量指向的对象是不是同一对象。
String str1 = new String("abc"); String str2 = new String("abc"); System.out.println(str1 == str2); System.out.println(str1.equals(str2));
“==”比较的是地址,str1和str2在堆中的地址是不同的,所以结果返回false,由于String类型自定义了equals方法,此equals方法比较的是对象的内容,所以结果返回true。
因此运行结果依次为false true。
public class Test { public Test() {} public static void main(String[] args) { Test a = new Test(); Test b = new Test(); Test c = a; System.out.println(a.equals(b)); System.out.println(a.equals(c)); } }
本身定义的的Test类,并无自定义equals方法,所以euqals方法和“==”的做用是同样的,比较的是对象的地址,也就是说判断两个对象是不是同一个。a和b中存储的地址分别是两个不一样对象的地址,c被赋值了a中存储的地址,也就是说a和c指向的是同一个对象。
所以,运行结果依次是:false true。
运算符“==”只是用来比较两个变量在栈中存放的值是否相同。
equals是类的成员方法,通常用来比较两个独立对象的内容是否相同(要看具体的定义)。若是自定义的类中没有定义equals方法,则会继承Object类的equals方法,其做用与“==”相同。