Java中==和equals的区别

今天被某女程序员问了下面的问题:
“JAVA 两个Double类型比较大小 用equals是可以的吧?”
本人是属于比较爆的脾气,对于弱智问题(请原谅)其实是不屑于回答的,但是又不能不回答于是乎有了这篇文章。
先给出一份java面试题:
1 String str1 = new String("hello");
2 String str2 = new String("hello");
3 System.out.println(str1==str2);
4 System.out.println(str1.equals(str2));
会发现3和4的输出结果是不一样的,这说明==和euqals是不一样的(废话)那么:
5 Double a = new Double("1.1");
6 double b = new Double("1.1");
7 System.out.println(a==b);
8 System.out.println(a.equals(b));
7和8的输出又是一样的,这拿到说明==和euqals是一样的?
那么==和euqals到底比较的是什么?
首先引用《Java编程思想》一书中的原话:
“关系操作符(也就是‘==’)生成的是一个boolean结果,它们计算的是操作数的值之间的关系”。
什么?听不懂,那么下面的懂吧?
9   int i = 5;
10  int j = 5;
11 System.out.println(i==j);
Java 提供两种不同的类型:引用类型和原始类型(或内置类型)
i和j是原始类型 i和j比较的就是它们的值,str1和str2是引用类型如果有c语言基础的话就知道他们可以理解为指针地址,str1和str2是不同的对象所以它们的值不一样所以用==就是false的
以下代码是String类的equals源码:
   /**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String) anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                            return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
 
可以看到String最终还是讲值转为char(原始类型)用==作比较的
那么?为什么Double类型可以用==直接比较呢?
因为java是面向对象的语言而原始类型不是对象()太不和谐了)于是在 java.lang包下提供了提供这些原始类型(Boolean, Byte, Short, Integer, Long, Float, Double, Character)的包装类,而包装类有一个基本特性(装箱,拆箱):
装箱:是指基本类型变为相应包装类的过程,如Integer a=Integer.valueOf(100);或者int a=100;Integer b=new Integer(a);这里的Integer.valueOf(100)和new Integer(a)就是装箱,由基本数据类型构造出一个包装类的对象。
拆箱:就是装箱的逆过程。如Integer a=new Integer(100);int b=a.intValue();这里的a.intValue()就是拆箱的过程,由一个包装类对象转换到相应的基本数据类型。
于是原始类型和引用类型(对象)之间就能随意转换了,科技以懒为本,这个转换还是要写代码太麻烦了于是就有了自动装箱、拆箱:
自动装箱、拆箱:指编译器帮助开发人员完成包装类的装箱和拆箱过程
所以包装类和原始类型混用时==比较,其实比较的还是原始类型,所以对于包装类==和equals是一样的。
好了,到此结束收工!
posted @ 2017-02-06 16:44  都市沽酒人  Views(162)  Comments(0)    收藏  举报