从 Java5 开始,7 种数字原始类型的包装类 (不包含 Boolean) 都提供了一个静态字段 SIZE, 用来表示该类型以 bit 为单位的长度。例如:
System.out.println("char = " + Character.SIZE + "bit"); System.out.println("byte = " + Byte.SIZE + "bit"); System.out.println("short = " + Short.SIZE + "bit"); System.out.println("int = " + Integer.SIZE + "bit"); System.out.println("long = " + Long.SIZE + "bit"); System.out.println("float = " + Float.SIZE + "bit"); System.out.println("double = " + Double.SIZE + "bit"); //char = 16bit //byte = 8bit //short = 16bit //int = 32bit //long = 64bit //float = 32bit //double = 64bit
在 Java8 中,它们都提供了一个 BYTES 字段,以 byte 为单位来表示该类型的长度,以便用于无法被 8 整除的情况。例如:
System.out.println("char = " + Character.BYTES + "byte"); System.out.println("byte = " + Byte.BYTES + "byte"); System.out.println("short = " + Short.BYTES + "byte"); System.out.println("int = " + Integer.BYTES + "byte"); System.out.println("long = " + Long.BYTES + "byte"); System.out.println("float = " + Float.BYTES + "byte"); System.out.println("double = " + Double.BYTES + "byte"); //char = 2byte //byte = 1byte //short = 2byte //int = 4byte //long = 8byte //float = 4byte //double = 8byte
所有 8 种原始类型包装类现在都提供了一个静态的 hashCode() 方法,用来返回与实例方法相同的哈希码,这样就不再需要经历装箱/拆箱的过程了。例如:
System.out.println("char = " + Character.hashCode('A')); System.out.println("byte = " + Byte.hashCode((byte)1)); System.out.println("short = " + Short.hashCode((short)1)); System.out.println("int = " + Integer.hashCode(1)); System.out.println("long = " + Long.hashCode(1L)); System.out.println("float = " + Float.hashCode((float)1)); System.out.println("double = " + Double.hashCode(1)); //char = 65 //byte = 1 //short = 1 //int = 1 //long = 1 //float = 1065353216 //double = 1072693248
Short、Integer、Long、Float 和 Double 这 5 种类型,现在分别提供了静态方法 sum()、max() 和 min(), 用来在流操作中作为聚合函数使用。例如:
// 以 int 为例 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); // 求和 int sum = list.stream().reduce(Integer::sum).orElse(0); System.out.println("sum = " + sum); // sum = 45 // 最大值 int max = list.stream().reduce(Integer::max).orElse(0); System.out.println("max = " + max); // max = 9 // 最小值 int min = list.stream().reduce(Integer::min).orElse(0); System.out.println("min= " + min); // min= 1
出于相同的原因,Boolean 类现在也包含了静态方法 logicalAnd、logicalor 和 logicalXor。它们定义如下:
static boolean logicalAnd(boolean a, boolean b) 返回对指定布尔操作数应用逻辑 AND 运算符的结果。
static boolean logicalOr(boolean a, boolean b) 返回对指定布尔操作数应用逻辑 OR 运算符的结果。
static boolean logicalXor(boolean a, boolean b) 返回对指定布尔操作数应用逻辑 XOR 运算符的结果。
例如:
boolean flag1 = true; boolean flag2 = false; // 使用 Boolean.logicalAnd 方法进行逻辑与操作 boolean result = Boolean.logicalAnd(flag1, flag2); System.out.println("逻辑与的结果: " + result); //逻辑与的结果: false List<Boolean> booleanList = Arrays.asList(true, false, true); boolean finalResult = booleanList.stream() .reduce(true, Boolean::logicalAnd); System.out.println("列表中元素逻辑与的结果: " + finalResult); //列表中元素逻辑与的结果: false
Integer 类现在支持无符号数学计算。例如,与以往 Byte 表示从 -128 到 127 的范围不同,你现在可以调用静态方法 Byte.toUnsignedInt(b) 来获取一个从 0 到 255 的值。一般来说,使用无符号数字,你会丢失负数并获得原来两倍范围的正数。Byte 和 Short 类中新增了 toUnsignedInt() 方法,而 Byte、Short 和 Integer 类中新增了 toUnsignedLong() 方法。例如:
byte b = (byte)0xF8; System.out.println("b = " + b); // -8 // 1111 1000 => 248 System.out.println(Byte.toUnsignedInt(b));
Integer 和 Long 类中新增了处理无符号值的 compareUnsigned()、divideUnsigned() 和 remainderUnsigned() 方法。你不需要特殊的方法来计算加法、减法和乘法。操作符 + 和 - 已经能够正确地处理无符号值。由于大于 Integer.MAX_VALUE 的无符号整数相乘会导致溢出,所以你应该调用toUnsignedLong 将它们作为长整型值相乘。例如:
int a = (int)0xFF000010; int b = (int)0xFF000020; // 有符号显示 System.out.println("a = " + a); // a = -16777200 System.out.println("b = " + b); // b = -16777184 // 无符号显示 System.out.println(Integer.toUnsignedLong(a)); // 4278190096 System.out.println(Integer.toUnsignedLong(b)); // 4278190112 // 比较数值 // 如果 x == y,数值为 0 // 如果 x < y,数值为小于 0 的无符号数值 // 如果 x > y,数值为大于 0 的无符号数值 // 4278190096 < 4278190112 => -1 int result = Integer.compareUnsigned(a, b); // -1 System.out.println("result= " + result);
注意:为了使用无符号数字,你需要对二进制数字及负数的二进制表示有清晰的理解。在 C 和 C++ 中,混合使用有符号类型和无符号类型容易导致一些难以察觉的错误。Java 明智地选择了远离这类错误,并且多年来一直成功地只使用有符号的数字。使用无符号数字的主要原因是某些文件格式或者网络协议的需要。
Float 和 Double 类现在新增了静态方法 isFinite()。如果 x 不是正无穷大、负无穷大或者 NaN(非数字), 那么调用 Double.isFinite(x) 会返回 true。在过去,你不得不调用实例方法 isInFinite 和 isNaN 来获得同样的结果。
最后,BigInteger 类增加了实例方法 (long|int|short|byte) ValueExact, 分别用来返回 long、int、short或者 byte, 并且当值不在目标范围内时抛出一个 ArithmeticException 异常。
byte byteValueExact() 将 BigInteger 转换为字节,检查是否丢失信息。
shortValueExact() 将 BigInteger 转换为 short,检查是否丢失信息。
intValueExact() 将 BigInteger 转换为 int,检查丢失的信息。
longValueExact() 将 BigInteger 转换为 long,检查丢失的信息。