JAVA 并不是纯面向对象的语言, 其中的基本数据类型如 int, float, boolean 并不是面向对象的, 但也可以通过基本类型对应的包装类, 来支持对象操作。

层次结构如下: 对应的数字基本类型包装类, 都继承自 Number 类:

基本类型包装类
byteByte
booleanBoolean
shortShort
charCharacter
intInteger
longLong
floatFloat
doubleDouble

自动装箱/拆箱机制

包装类属于对象, 而对象就需要用对象的方式来使用:

public static void main(String[] args) {
	Integer i = new Integer(10);
}

像这样创建一个 值为10的 Integer 对象。

对于基本类型的包装类, JAVA提供了一个自动装箱的机制来避免繁琐的对象声明。

public static void main(String[] args) {
	Integer i = 10;
	Integer i = Integer.valueOf(10); // 等价
	int a = i; // 也支持拆箱
}

正因为这个机制的存在, 我们不仅可以方便的包装类型轻松地参与到基本类型的运算中。但类之间判断相等通常需要重载并调用 .equals 方法, 包装类若直接用等号:

public static void main(String[] args) {
	Integer a = 7749, b = 7749;
	System.out.println(a == b);
}

则会得到错误的结果 false

不过 Integer 类存在一个 IntegerCache, 会缓存值在 范围内的 对象, 当创建一个在该范围内的对象后再去创建相等的对象, 新对象会直接是原对象的引用, 这是为了提升效率,因为小的数使用频率非常高,有些时候并不需要创建那么多对象,创建对象越多,内存也会消耗更多。 这也会导致当值在 范围内时, 通过 == 判断对象地址时返回为 true

特殊包装类

注意这些包装类不支持自动装箱和拆箱。

BigInteger

即使是最大的long类型,也只能表示64bit的数据,无法表示一个非常大的数,但是BigInteger没有这些限制,我们可以让他等于一个非常大的数字:

public static void main(String[] args) {
	BigInteger i = BigInteger.valueOf(Long.MAX_VALUE);
	
}

BigDecimal

浮点类型精度有限,对于需要精确计算的场景可以使用 BigDecimal 类来实现。

public static void main(String[] args) {
    BigDecimal i = BigDecimal.valueOf(10);
    i = i.divide(BigDecimal.valueOf(3), 100, RoundingMode.CEILING);
      //计算10/3的结果,精确到小数点后100位
      //RoundingMode是舍入模式,就是精确到最后一位时,该怎么处理,这里CEILING表示向上取整
    System.out.println(i);
}

但只能进行基本的运算, 如果想调用 Math 库的方法还是得用 .doubleValue() 获得对应的 double 类型值。