Java易错点2

这是我参与更文挑战的第9天,活动详情查看: 更文挑战

Java易错点2

如有理解错误的话,恳请大家指正!!!

Integer

  • == :对于基本数据类型的变量, **==**是直接对其值进行比较。对于引用数据类型的变量对象,则是对其内存地址的比较。

  • equals最常用的说法是值的比较,原因就是equals是可以被重写的,比如Intenger的equals就是对值的比较,而在Object中,equals就是用 ==做的比较,此时和==是没有区别的。

    看Object的源码

     public boolean equals(Object obj) {
            return (this == obj);
        }
    复制代码

    再看Integer的源码

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    复制代码

    再看看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;
    }
    复制代码

示例代码

package com.wangscaler;

public class TestInteger {
    public static void main(String[] args) {
        Integer a = 127;
        Integer b = 127;
        Integer bb = new Integer(127);
        int c = 127;
        Integer d = 128;
        Integer e = 128;
        int f = 128;
        System.out.println(a.equals(b));
        System.out.println(a == b);
        System.out.println(b == bb);
        System.out.println(a.equals(c));
        System.out.println(a == c);
        System.out.println(d.equals(e));
        System.out.println(d == e);
        System.out.println(d.equals(f));
        System.out.println(d == f);
    }
}

复制代码

执行结果

true
true
false
true
true
true
false
true
true
复制代码

原理

基本数据类型作为常量在方法区中的常量池里面以HashSet策略存储起来的,一个常量只会对应一个地址,像在上节内存里写的,字符串”wang“和people对象里的name值”wang“,是指向的同一个地址。因此基本数据类型和String常量是可以直接通过==来直接比较的。

然而,为什么Integer的值为127时, System.out.println(a == b);比较是相等的,而在System.out.println(d == e);却是不相等呢?带着疑惑我打开了打开Integer的源码,终于发现了问题所在。

源码如下:

//IntegerCache.low==-127
//IntegerCache.high==128
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
复制代码
/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 *
 * The cache is initialized on first usage.  The size of the cache
 * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
 * During VM initialization, java.lang.Integer.IntegerCache.high property
 * may be set and saved in the private system properties in the
 * sun.misc.VM class.
 */

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}
复制代码

有上述源码不难看出,当Integer的值在-127到128之间,他是通过IntegerCache在数组中(上述的常量池)取出的,而超过范围的则是重新new的,所以

System.out.println(b == bb);的结果是false。

在Integer的equals就是值的比较,所以equals比较的都是true就不难理解了。

十进制转二进制的方法

1、取余法

2、快捷法

java8.png

switch语句

每个case语句的结尾需要包含break;(注意:华为的编程规范强调1、必须得有default语句的代码(enum除外)2、enum如果不写default的话,必须将enum的所有情况写上)

错误示例代码

package com.wangscaler;

public class TestSwitch {

    public static void main(String[] args) {
        TestSwitch testSwitch =new TestSwitch();
        testSwitch.typePeople(People.MAN);
    }

    enum People {
        MAN, WOMEN, OTHER
    }

    private void typePeople(People people) {
        switch (people) {
            case MAN:
                System.out.println("This is a Man");
            case WOMEN:
                System.out.println("This is a Women");
            case OTHER:
                System.out.println("I do not Known");

        }
    }
}
复制代码

执行结果

This is a Man
This is a Women
I do not Known
复制代码

原因

swith语句执行的时候遇到break才会结束,如果没有break就会从执行的case处顺序向下执行。正确的做法是在每个case语句最后加上break;

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享