java的基本数据类型
java有八种基本数据类型可以不必new 而直接使用 分别为4种数值型 byte short int long
2种浮点型 float double
1种布尔型 boolean
一种字符型 char
包装类型
八种基本数据类型分别对应它们的包装类,包装类可以理解为基本数据类型的对象形式
封箱
在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行:
Integer i = new Integer(10);
而在从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了:
Integer i = 10;
自动根据值创建Integer 对象称为封箱
与之相反 将包装类型自动转换为基本类型的操作为拆箱
例如
Integer it = 1;
int i = it; //拆箱操作
实现原理
由反编译的字节码可以看出,在执行封箱操作时底层调用了Integer的valueOf(int) 方法
在执行拆箱操作时,底层调用了Integer 的intValue()方法
面试常见问题
public class Main {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);
System.out.println(i3==i4);
}
}
输出结果为 true false
由valueOf源码可知
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
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() {}
}
由源代码可以看出使用valueOf方法创建一个对象时 如果对象的值在-128 ~ 127 之间的话,便返回指向IntegerCache.cache中已经存在的对象的引用;
否则创建一个新的Integer对象。
Double 类型的valueOf()
public static Double valueOf(String s) throws NumberFormatException {
return new Double(parseDouble(s));
}
/**
* Returns a {@code Double} instance representing the specified
* {@code double} value.
* If a new {@code Double} instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Double(double)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param d a double value.
* @return a {@code Double} instance representing {@code d}.
* @since 1.5
*/
public static Double valueOf(double d) {
return new Double(d);
}
由源码可以看出Double 类型调用valueOf方法时 会直接返回一个新的Double对象
案例
Double d1 = 1.0;
Double d2 = 1.0;
System.out.println(d1==d2);
System.out.println(d1.equals(d2));
输出:false
true
Boolean类型的valueof()
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
案例
Boolean i11 = false;
Boolean i21 = false;
Boolean i31 = true;
Boolean i41 = true;System.out.println(i11==i21);
System.out.println(i31==i41);
true
true
Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
案例 float
Float f1 = 1.1f;
Float f2 = 1.1f;
System.out.println(f1==f2);
输出 false
案例 ShortShort s1 =1;
Short s2 =1;
Short s3 =128;
Short s4 =128;
System.out.println(s1==s2);
System.out.println(s3==s4);输出 true
false
案例 Byte
valueOf源码
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
Byte b1 = 1;
Byte b2 = 1;
Byte b3 = 127;
Byte b4 = 127;
System.out.println(b1==b2);
System.out.println(b3==b4);
输出 true
true
案例 character
源码
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}可以看到实现与Integer 类似
Character c1 =1;
Character c2 =1;
Character c3 =128;
Character c4 =128;
System.out.println(c1==c2);
System.out.println(c3==c4);
案例Long
源码
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);
}
Long l1 = 1L;
Long l2 = 1L;
Long l3 = 128L;
Long l4 = 128L;
System.out.println(l1==l2);
System.out.println(l3==l4);
输出 true
false
小结