Java 包装类
Java 中有些类只能操作对象,因此 Java 的基本数据类型都有一个对应的包装类。
- byte:Byte
- short:Short
- int:Integer
- long:Long
- float:Float
- double:Double
- char:Character
- boolean:Boolean
- void:Void
包装类与基本数据类型转换
包装类与基本数据类型的转换代码结构是类似的。
将基本类型转换为包装类的过程,一般称为“装箱”,而将包装类型转换为基本类型的过程,则称为“拆箱”。
装箱拆箱的写法比较繁琐,Java 5 以后引入了自动装箱和拆箱技术,可以直接将基本类型赋值给引用类型,反之亦可。
自动装箱/拆箱是 Java 编译器提供的能力,编译后会替换为调用对应的 valueOf / xxxValue 方法。
基本数据类型转包装类
- ❑ valueOf (推荐)
Integer a = Integer.valueOf(1);
- ❑ 构造方法
Integer b = new Integer(1);
包装类转基本数据类型 xxxValue
int c = b.intValue(); // 注意 b 不能为 null
包装类与字符串转换
字符串转基本数据类型 / 包装类
- ❑ parseXXX 字符串转基本数据类型
double pai = Double.parseDouble("3.14");
- ❑ valueOf 字符串转包装类
Double pai = Double.valueOf("3.14");
包装类转字符串
- ❑ + 连接符
Double pai = Double.valueOf("3.14");
String str = pai + "";
- ❑ toString
Double pai = Double.valueOf("3.14");
String str = pai.toString();
对于整数类型,字符串表示除了默认的十进制外,还可以表示为其他进制,如二进制、八进制和十六进制,包装类有静态方法进行相互转换。
❑ toBinaryString 转二进制
❑ toOctalString 转八进制
❑ toHexString 转十六进
包装类共性
equals
所有包装类都重写了该实现,实际比较用的是其包装的基本类型值。
public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}return false;
}
public boolean equals(Object obj) {return (obj instanceof Float) && (floatToIntBits(((Float)obj).value) == floatToIntBits(value));
}
floatToIntBits() 会将 float 的二进制表示视为 int,只有两个 float 的二进制表示完全一样的时候,equals 才会返回 true。
hashCode
hashCode 和 equals 方法联系密切,如果 equals 方法返回 true,则 hashCode 也必须一样,反之不要求。
- Byte、Short、Integer、Character
public int hashCode() {return (int)value;
}
- Long
public int hashCode() {return (int)(value ^ (value >>> 32));
}
Long 是高 32 位与低 32 位进行位异或操作。
- Boolean
public int hashCode() {return value ? 1231 : 1237;
}
根据值返回两个质数,质数用于哈希时比较好,不容易冲突。
- Float
public int hashCode() {return floatToIntBits(value);
}
- Double
public int hashCode() {long bits = doubleToLongBits(value);return(int)(bits ^ (bits >>> 32));
}
实现了 Comparable 接口
数值父类 Number
byte byteValue()
short shortValue()
int intValue()
long longValue()
float floatValue()
double doubleValue()
通过这些方法,包装类实例可以返回任意的基本数值类型。
不可变性
包装类都是不可变类。
- 所有包装类都声明为了 final,不能被继承。
- 内部基本类型值是私有的,且声明为了 final。
- 没有定义 setter 方法。
参考:《Java 编程的逻辑》马俊昌