Java的那些坑(一)

1,== 和equals
基本数据类型,保存在栈中,用==进行数值判断。
而引用数据类型比如Object,对象实体保存在堆中,对象引用地址保存在栈中,则==用来比较地址是否相等,而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类型的可以比较对对象的内容是否相等,equals和hashcode是子类可以重写的方法,子类可以根据自己的具体业务重写达到业务的需求。String类型的数据会涉及到jvm编译时优化问题比如下列

package com.sparkhuu.base;


public class StringTest {
    public static void main(String[] args) {
        String s1 = "a" + "b" + 1; // 编译时自动优化为:"ab1"
        String s2 = "ab1";
        // == 当比较基本数据类型时,比较数值,当比较引用数据类型时,比较引用地址
        System.out.println(s1 == s2);
        // equals 默认比较对象的地址, 可被重写,String已经重写了equals方法
        System.out.println(s1.equals(s2));
        String a = "1";
        final String testA = "1";
        String b = a + "2" + 3; // 编译时不会优化 b,c不是同一个对象,但b,c值相同 String重写了equals方法
        String c = "123";
        String testB = testA + "2" + 3;
        System.out.println(testB == c);
        System.out.println(testB.equals(c));
        System.out.println(b == c); 
        System.out.println(b.equals(c));
        String eString = "a";
        String fString = eString + "b";
        String gString = "ab";
        String hString = new String(gString);// 通过new的都只有在运行时才能确定
        System.out.println(fString == gString);
        System.out.println(hString == gString);
        System.out.println(hString.intern() == gString.intern());

    }   
}

结果为

true
true
true
true
false
true
false
false
true

2,基本数据类型的封装类
int –> Integer
char –> Character
double –>Double等
这里会涉及到装包和拆包
如下测试

package com.sparkhuu.base;

public class BaseNumberTest {
    public static void main(String[] args) {
        Integer a = 1;
        Integer b = 1;
        Integer e = -127;
        Integer f = -127;
        // Integer.valueOf(); [-128 127]之前是被cache的 所以是同一个对象 而其他范围会new Integer() 所以不是同一个对象
        Integer c = 200;
        Integer d = 200;
        System.out.println(a == b);
        System.out.println(e == f);
        System.out.println(c == d);

        char x = '中';
        char x1 = 'a';
        byte y = 'a';

        Boolean tr = true;
        Boolean shBoolean = true;
        System.out.println(tr == shBoolean);

    }
}

结果为

true
true
false
true

主要原因是基本数据类型转化为封装类的时候会调用封装类的init,而封装类的部分代码进行了cache,
Integer,Short,Long的cache范围是-128到127,其中Integer可以通过配置修改范围,而Short和Long则不行。
Boolean 的cache范围是true, false,
Characher全部缓存
Double,Float没有缓存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值