的用法浅析,的用法比较

用于,比较的是两个变量的值是否相等,这里首先梳理一下java中的数据类型,而引用类型就是除了值类型之外的其他类型,说到java中的equals与==的用法

图片 3

java中equals与==的用法相比,java中equals用法

聊到java中的equals与==的用法,这里首先梳理一下java中的数据类型,首要分为两大类:值类型和援引类型,值类型也正是主导数据类型,而引用类型正是除了值类型之外的其他品类。

1.equals用法

个体的综合计算:

  • 用来String类型之间的比较时,调用的是String类的equals()方法,比较的是字符串的开始和结果而不是地方,而且只好用于比较String类型,因为StringBuffer和StringBuilder类中都尚无equals()方法。

  • 用来其余项目之间(富含蕴涵一个Sting类型的状态)的相比较时,以o1.equals(o2)为例:
    若o1是String类型,则调用的时String类的equals方法,重回值为false;若o1不是String类型,则调用的是Object类的equals()方法(此时与==用法同样),比较的是引用变量的地点实际不是内容。

 1     private static void equalsAnal() {
 2         String s1 = "hello";
 3         String s2 = "hello";
 4         String s3 = new String("hello");
 5         String s4 = new String("hello");
 6         String s5 = new String(new StringBuffer("hello"));
 7         
 8         StringBuffer s6 = new StringBuffer("hello");
 9         StringBuffer s7 = new StringBuffer("hello");
10         
11         System.out.println(s1.equals(s2));//true
12         System.out.println(s3.equals(s4));//true
13         
14         System.out.println(s1.equals(s3));//true
15         
16         System.out.println(s1.equals(s5));//true
17         System.out.println(s3.equals(s5));//true
18         
19         System.out.println(s6.equals(s7));//false
20         System.out.println(s1.equals(s6));//false
21         System.out.println(s3.equals(s6));//false
22         System.out.println(s5.equals(s6));//false
23         System.out.println(s6.equals(s1));//false
24     }

对于上述代码的结果,大家得以组合String类以及Object类的源码来开展分析:

 1   //String类中的equals方法  
 2   public boolean equals(Object anObject) {
 3         if (this == anObject) {
 4             return true;
 5         }
 6         if (anObject instanceof String) {
 7             String anotherString = (String)anObject;
 8             int n = value.length;
 9             if (n == anotherString.value.length) {
10                 char v1[] = value;
11                 char v2[] = anotherString.value;
12                 int i = 0;
13                 while (n-- != 0) {
14                     if (v1[i] != v2[i])
15                         return false;
16                     i++;
17                 }
18                 return true;
19             }
20         }
21         return false;
22     }

1     //Object类中的equals方法
2      public boolean equals(Object obj) {
3         return (this == obj);
4     }
  • 基本数据类型(8种):byte、short、int、long、float、double、char、boolean
  • 引用类型(3种):类(Class)类型、接口(Interface)类型、数组(Array)类型

 2. ==用法

 ==是一种关系运算符,用于中央数据类型时,比较的是三个变量的值是不是等于;用于引用类型时,比较的是四个援引变量的地点是不是一律。

 1         int a = 10, b = 10;
 2         char ch1 = 'A', ch2 = 'A';
 3         String str1 = "hello";
 4         String str2 = "hello";
 5         Integer n1 = new Integer(10);
 6         Integer n2 = new Integer(10);
 7         
 8         System.out.println(a == b);//true
 9         System.out.println(ch1 == ch2);//true
10         System.out.println(str1 == str2);//true
11         System.out.println(n1 == n2);//false

1.equals用法总计

村办的归结如下:

  • 在Object类中定义了八个原有的equals方法,那么些办法的一举一动是相比较援引变量中蕴藏的靶子在堆内部存款和储蓄器中的地方,使用“==”达成。
  • 在一部分类库个中equals方法被重写了,如String、包装类、Date等等。在那几个类个中equals有其自己的贯彻,而不再是比较对象在堆内部存储器中的寄放地方了。 

  • 对于引用类型之间开展equals相比较,在未有重写equals方法的事态下,他们中间的比较依旧堆内部存储器中的寄放的地方值,跟双等号(“==”)的结果一律;假设被重写,则根据重写的渴求来拓宽相比。

  • equals方法不能够用于中央数据类型的比较,可是可以用于着力项目标卷入类,而且相比较的是指标的内容并非位置。

上面给出一些源码来一发理解:

 1     //Object类中的equals方法
 2     public boolean equals(Object obj) {
 3         return (this == obj);
 4     }
 5 
 6     //String类中的equals方法,重写了Object类的equals方法
 7     public boolean equals(Object anObject) {
 8         if (this == anObject) {
 9             return true;
10         }
11         if (anObject instanceof String) {
12             String anotherString = (String)anObject;
13             int n = value.length;
14             if (n == anotherString.value.length) {
15                 char v1[] = value;
16                 char v2[] = anotherString.value;
17                 int i = 0;
18                 while (n-- != 0) {
19                     if (v1[i] != v2[i])
20                         return false;
21                     i++;
22                 }
23                 return true;
24             }
25         }
26         return false;
27     }
28 
29     //Integer类中的equals方法,重写了Object类的equals方法,其他包装类也重写了equals方法
30     public boolean equals(Object obj) {
31         if (obj instanceof Integer) {
32             return value == ((Integer)obj).intValue();
33         }
34         return false;
35     }
36 
37     //Date类中的equals方法,重写了Object类的equals方法
38     public boolean equals(Object obj) {
39         return obj instanceof Date && getTime() == ((Date) obj).getTime();
40     }

 因而,当且仅当调用的是Object类的equals方法时,equals与“==”的成效同样,比较的是指标在堆内部存款和储蓄器中的地点;而当调用的是其他类重写过后的equals方法时,经常来讲相比的是指标的剧情并不是地点。具体示比方下:

图片 1图片 2

 1         /*
 2          * StringBuffer和StringBuilder类都没有重写equals方法
 3          *     所以此处调用的是Object类的equals方法,比较的是地址
 4          */
 5         StringBuffer buffer1 = new StringBuffer("hello");
 6         StringBuffer buffer2 = new StringBuffer("hello");
 7         System.out.println(buffer1.equals(buffer2));//false
 8         System.out.println(buffer1 == buffer2);//false
 9 
10         /*
11          * String类重写了Object类的equals方法
12          *     所以此处调用的是String类的equals方法,比较的是内容
13          */
14         String s1 = "hello";
15         String s2 = "hello";
16         String s3 = new String("hello");
17         String s4 = new String("hello");
18         System.out.println(s1.equals(s2));//true
19         System.out.println(s1.equals(s3));//true
20         System.out.println(s3.equals(s4));//true
21 
22         /*
23          * Integer包装类重写了Object类的equals方法
24          *     所以此处调用的是Integer类的equals方法,比较的是内容
25          */
26         Integer integer = new Integer(100);
27         System.out.println(integer.equals(new Integer(100)));//true

View Code

3.用法比较

 1         String s1 = "hello";
 2         String s2 = "hello";
 3         String s3 = new String("hello");
 4         String s4 = new String("hello");
 5         String s5 = new String(new StringBuffer("hello"));
 6         
 7         StringBuffer s6 = new StringBuffer("hello");
 8         StringBuffer s7 = new StringBuffer("hello");
 9         
10         System.out.println(s1.equals(s2));//true
11         System.out.println(s1==(s2));//true
12         
13         System.out.println(s3.equals(s4));//true
14         System.out.println(s3==(s4));//false
15         
16         System.out.println(s1.equals(s3));//true
17         System.out.println(s1==(s3));//false        
18         
19         System.out.println(s1.equals(s5));//true
20         System.out.println(s1==(s5));//false
21         
22         System.out.println(s3.equals(s5));//true
23         System.out.println(s3==(s5));//false
24         
25         System.out.println(s6.equals(s7));//false
26         System.out.println(s1.equals(s6));//false
27         System.out.println(s3.equals(s6));//false
28         System.out.println(s5.equals(s6));//false
29         System.out.println(s6.equals(s1));//false

 综上所述,equals和==用法一样的景况:

  • 字符串为主导数据类型String的变量;
  • 相比较的是八个非String类型的引用变量。

 

1.equals用法 个人的归咎计算:
用于String类型之间的可比时,调用的是String类的equals()方法,比较…

2.==用法计算

双等号(“==”)是一种关系运算符,它的用法相比较轻易,首要分为三种意况:

  • 用于着力数据类型之间的比较:相比较的是变量的值(注意此时不确定必要“==”左右两侧数据类型严苛平等)
  • 用以援引类型之间的可比:比较的是引用对象在堆内部存款和储蓄器中的地址

此处差非常的少举了多少个例证:

 1         //基本数据类型的比较
 2         int a=10, b=10;
 3         char ch1='A', ch2='A';
 4         System.out.println(a == b);//true
 5         System.out.println(ch1 == ch2);//true
 6         
 7         //引用类型的比较
 8         Object o1 = new Object();
 9         Object o2 = new Object();
10         Object o3 = o1;
11         System.out.println(o1 == o2);//false
12         System.out.println(o1 == o3);//true

 1         int c = 65;
 2         float d = 65.0f;
 3         char ch = 'A';
 4 
 5         /*
 6          * 用于基本数据类型之间,比较的是变量的值
 7          *     注意:此时不一定要求数据类型严格一致
 8          */
 9         System.out.println(c == d);//true
10         System.out.println(c == ch);//true
11         System.out.println((d == ch));//true

 

 3.相比分析

大家平常弄不驾驭equals与==的用法,是因为我们从没结合JDK源码系统地总括过它们,这里先抛出一段代码:

 1         String s1 = "hello";
 2         String s2 = "hello";
 3         String s3 = new String("hello");
 4         String s4 = new String("hello");
 5         System.out.println(s1.equals(s2));//true
 6         System.out.println(s1 == s2);//true
 7         
 8         System.out.println(s1.equals(s3));//true
 9         System.out.println(s1 == s3);//false
10         
11         System.out.println(s3.equals(s4));//true
12         System.out.println(s3 == s4);//false

有了事先的一些学习,大家来剖判一下这段代码:

  • 是因为这里的对象都以String类型,所以调用的都以String类的equals方法,相比的是字符串的原委,所以结果都以true。
  • 不过,代码的第6行中,“==”比较的是七个引用变量s1和s2所针对的对象的地方,结果为true;而第12行,这里的“==”相比较的也是多个援引变量s3和s4所针对的靶子的地方,结果为false。

那么为啥第6行和第12行的结果区别呢?

 那就事关到字符串常量的三种创立情势“String s1 = “hello””和“String s3 =
new
String(“hello”)”的分别了,这里用二个图来申明:

图片 3

透过上海体育场地,咱们对于那三种字符串常量的始建格局得以计算如下:

  • 因而“String s1 =
    “hello””格局开创的话,JVM要先反省常量池中是或不是曾经包罗有“hello”,若有,则将其地方赋给s1;不然将字符串常量“hello”存款和储蓄在常量池中,并赶回存款和储蓄地方;
  • 经过“String s3 = new
    String(“hello”)”创造,JVM须要先在堆中开采一段空间用于存储new出来的靶子,又由于“hello”是三个字符串常量,所以要求将其坐落常量池中,并赶回其累积地点。

为此,对于代码中第6行的“s1 ==
s2”,由于s1与s2都指向的是字符串常量池中“hello”的地点,所以结果为true;而对此第12行的“s3
== s4”,由于s3与s4指向的是堆中的多个例外的靶子,所以结果为false。