比较String对象的两种初始化方式

 

在java中, String对象的初始化方式有两种:一种是使用字符串变量, 一种是使用new关键字. 而对于字符串的比较也有两种方式: 一种是使用"=="符号, 一种是使用equals方式, 以下是实际中使用的结果:

public static void main(String[] args){
        
        String a = "123";
        System.out.println((a == "123") + "," + (a.equals("123"))); // true,true
        String b = new String("123");
        System.out.println((b == "123") + "," + (b.equals("123"))); // false,true        
}

发现:

对于使用"=="进行对象的比较返回的结果是不一样的, 为什么呢?

首先, 了解一下变量在内存中如何保存:

由上图, 基本数据类型的变量保存在变量区, 而构造数据类型的变量保存在堆区, 两者均将内存中内容保存地址存储在栈中与变量名对应.

其次, "=="和"equals"本质上都是比较地址引用, 只是某些类重写equals达到比较内容的目的(比如String类)

所以, 对于String对象来说, 不同的初始化方式会使用不同的变量机制, 使用变量直接初始化对象时两种比较方式的结果相同

 

拓展:

对于String对象存在这样的现象, 那个对于Integer/Double呢?

     Integer c = 10;
        System.out.println((c == 10) + "," + (c.equals(10))); // true,true
        Integer d = new Integer(10);
        System.out.println((d == 10) + "," + (d.equals(10))); // true,true
        
        Double e = 20d;
        System.out.println((e == 20d) + "," + (e.equals(20d))); // true,true
        // System.out.println((e == 20) + "," + (e.equals(20))); // true,false
        Double f = new Double(20d);
        System.out.println((f == 20d) + "," + (f.equals(20d))); // true,true

结论是: 两种初始化方式的两种比较方式的结果都是true, 但也有特殊的情况存在(注掉的一行), 原因是"=="进行数值和地址的比较,而equals进行内容的比较.

 

对象间的比较

#java.lang.Object

1 public boolean equals(Object obj) {
2         return (this == obj);
3     }

由此可知,对象间的“==”其实是类似地址的比较,而equal在不进行重写的情况下同“==”一致

 

最终结论

1、对象的equal比较在不被重写的情况下与等号比较一致,属于类似地址的比较;

2、基本数据类型对象可以使用数值直接初始化,对象地址指向变量区,等号的比较为字符的比较,对于数值不考虑其数据类型,如new Double(20d)==20为true;

而equals由于被重写而异于等号比较。如:java.lang.Double,在比较对象非Double对象时均结果为false。

1 public boolean equals(Object obj) {
2     return (obj instanceof Double)
3            && (doubleToLongBits(((Double)obj).value) ==
4               doubleToLongBits(value));
5     }

基本数据类对象的一般类对象的等号比较和equals比较一致,规则同1。

----------------------------------

posted @ 2012-08-21 10:40  bluephaethon  阅读(1143)  评论(0)    收藏  举报