面试:==与equlas区别比较(看这一篇文章就够了)

217 阅读1分钟

一个在沪漂泊的90后程序员,只专注分享干货

每周末更新,您的点赞评论加关注是小编的莫大动力,奥利给~

或许您也有听过这样的总结 :== 的比较实际是:基本类型比较的是值,非基本类型比较的是内存地址 可能有人问为啥用删除线将总结划掉呢?一起来实践一下吧,或许您心里就会有自己的总结:

== 之间的比较

1、int 与 Integer、 new Integer 比较

结论:因为包装类Integer 和 基本数据类型int 比较时,java会自动拆箱为int ,然后进行比较,实际上就变为两个int变量的比较。

	int int1 = 165;
        Integer integer1 = 165;
        Integer newInteger1 = new Integer(165);

        System.out.println(int1 == integer1);						//true
        System.out.println(int1 == newInteger1);					//true

2、Integer 与 Integer 比较

分析:Byte、Short、Integer、Long这几个类型两个变量比较,首字母是大写哦,是非基本数据类型。这些类定义赋值其实就是一个装箱的过程,会调用valueOf方法

public static Long valueOf(long l) {
        final int offset = 128;
        if (l >= -128 && l <= 127) { // will cache
            return LongCache.cache[(int)l + offset];
        }
        return new Long(l);
    }

若在[-128, 127]区间内 ,则从高速缓冲存储器获取,比较结果为true,如果两个变量的值不在此区间,则比较结果为 false

	// Integer
        Integer integer1 = 165;
        Integer integer11 = 165;
        Integer integer2 = 35;
        Integer integer22 = 35;
        System.out.println(integer1 == integer11);					//false
        System.out.println(integer2 == integer22);					//true
	// Long
	Long long1 = 165L;
        Long long11 = 165L;
        Long long2 = 35L;
        Long long22 = 35L;

        System.out.println(long1 == long11);						// false
        System.out.println(long2 == long22);						// true

3、Integer 与 new Integer 比较

分析:Integer 定义的变量指向常量池、new Integer 指向的是 堆。两者的内存地址不一样

        Integer integer1 = 165;
        Integer newInteger1 = new Integer(165);
        
        System.out.println(integer1 == newInteger1);				//false
        System.out.println(integer1.equals(newInteger1));			 // true
        

4、new Integer与 new Integer 比较

分析:每new Integer 指向的是 堆都是一个新的地址,因此内存地址不一样。

        Integer newInteger1 = new Integer(165);
        Integer newInteger2 = new Integer(165);

        System.out.println(newInteger1 == newInteger2);				//false

5、+ 操作符混合比较

分析: int:int之间的运算操作符 就不用多说了,不论怎么操作他们的值相等就是true Integer:Integer 之间的运算操作符,依旧遵循在[-128, 127]区间内 ,则从高速缓冲存储器获取,比较结果为true,否则false String:str3 = str1+str4 在编译时,str1与str4 还未确定引用地址,而str3 、str5 都是已确定的字符串,因此str3在进行比较的时候,由于未确定引用地址 所以是false

        int int1 = 165;
        int int2 = 35;
        int int3 = 200;
        int int4 = int1 + int2;
        int int5 = 165 + 35;

        System.out.println(int3 == int4);						// true
        System.out.println(int3 == int5);						// true
        System.out.println(int4 == int5);						// true

	Integer iteger1 = 165;
        Integer iteger2 = 35;
        Integer iteger3 = 200;
        Integer iteger4= iteger1 + iteger2;
        Integer iteger5 = 165 + 35;

        System.out.println(iteger3 == iteger4);					// false
        System.out.println(iteger3 == iteger5);					// false
        System.out.println(iteger4 == iteger5);					// false

        String str1 = "a";
        String str2 = "b";
        String str3 = "ab";
        String str4 = str1 + str2;
        String str5 = "a" + "b";
        
        System.out.println(str3 == str4);						// false
        System.out.println(str3 == str5);						// true
        System.out.println(str4 == str5);						// false

注意: one:initA 和initB 都是已赋值的常量,因此它在类编译时就已经确定了引用地址。也就是说:String initStr = initA + initB; 等同于:String str3 = "a" + "b";

two:defaultA和defaultB虽然被定义为常量,但是它们没有被赋值,而是之后通过static块赋值,因此在执行运算符时,未能确定其何时赋值,性质类似于变量而非确定的字符串

   // one 示例
    public static final String initA = "a";
    public static final String initB = "b";

    // two 示例
    public static final String defaultA;  
    public static final String defaultB;
    static {
        defaultA = "a";
        defaultB = "b";
    }
    public static void main(String[] args) throws Exception {
        String str3 = "ab";
        String initStr = initA + initB;
        String defaultStr = defaultA + defaultB;

        System.out.println(str3 == initStr);            // true
        System.out.println(str3 == defaultStr);         // false
    }

6、String.intern()混合比较

分析:当调用str.intern()方法后,先在当前类的常量池中查找是否存在与str相等的数值 若存在则直接返回常量池中相应Strnig的引用; 若不存在,则会在常量池中创建一个等值的String,然后返回这个String在常量池中的引用;

	String str1 = "a";
        String str2 = new String("a");
        System.out.println(str1 == str2);						//false

        String str3 = str2.intern();
        System.out.println(str1 == str3);						// true

equals 之间的比较

分析:equals比较时,查看其equals方法是否被重写,如果没有被重写默认执行的是Object的equals方法,比较的是引用地址。

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

被重写比较的是:。例如:Integer、Double、String都是被重写过的equals方法

	int int1 = 6;
        Integer int2 = new Integer(6);
        System.out.println(int2.equals(int1));					// true

        double dou1 = 3;
        Double dou2 = new Double(3);
        System.out.println(dou2.equals(dou1));					// true

        String str1 ="one";
        String str2 = new String("one");
        System.out.println(str1.equals(str2));					// true

        StringBuffer buffer = new StringBuffer("one");
        System.out.println(buffer.equals("one"));				// false

结语: == 与equals用的也比较多,不过平常关注的比较少,看完是否有了自己的理解

我是不秃顶的山羊,一个沪漂90后普通程序员,不甘普通,只想找富婆

感谢各位的点赞 -评论- 关注,下期再见~

一个沪漂90后普通程序员,只专注分享干货

每周末更新,您的点赞评论加关注是小编的莫大动力,奥利给~