这是我参与更文挑战的第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、快捷法
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;