这次我们来看看Byte
类的源代码,基于 jdk1.8.0_181.jdk 版本 。
概要
Java的Byte
类主要是对byte
基本数据类型的封装,有着一个字段存放着对应的byte
数据值,另外提供了一些方法方便对byte
进行相关的操作。
类定义
public final class Byte extends Number implements Comparable<Byte>
Byte
类带有关键字final
,也就是不可以继承的,另外继承了Number
类,实现了Comparable
接口,也就是可以进行比较。
属性
public static final byte MIN_VALUE = -128;
public static final byte MAX_VALUE = 127;
定义了Byte
的范围大小,由于补码的关系,负数会比正数多一个值,MIN_VALUE
能取的值为 -2**8
,而MAX_VALUE
能取的值为2**8 - 1
,具体原码和补码的逻辑,可以参考下原码、反码、补码的产生、应用以及优缺点有哪些? - 知乎用户的回答 - 知乎,个人觉得讲解的不错。
public static final int SIZE = 8;
定义了byte
值的二进制补码格式的bit
位数,固定8位。
public static final int BYTES = SIZE / Byte.SIZE;
定义了byte
值的二进制补码格式的字节数,计算值固定为1。
@SuppressWarnings("unchecked")
public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
获取Byte
的类信息,Byte.TYPE == byte.class
,两者是等价的。
private final byte value;
Byte
因为是byte
的包装类,所以这里包含了对应的byte
基本类型数据的变量。
private static final long serialVersionUID = -7183698231559129828L;
内部类
private static class ByteCache {
private ByteCache(){}
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128));
}
}
这里定义了一个静态的嵌套类,内部定义了一个数组,大小为-(-128)+127+1=256
,包含了-128~127之间的值。静态块中初始化了数组的值。这里补充一个知识点,Java类的加载顺序,静态变量/代码块 -> 非静态变量/代码块 -> 构造方法
,相同部分里面是按照代码顺序进行加载,详细的内容可以自行搜索学习。
关于内部类的相关说明,可以参考官方的文档 Nested Classes 进行进一步的了解学习。
方法
构造方法
public Byte(byte value) {
this.value = value;
}
public Byte(String s) throws NumberFormatException {
this.value = parseByte(s, 10);
}
存在两个对应的构造方法,一个传入byte
值,一个是传入字符串解析,转换成10进制整数处理(注意的是这个方法可能会抛出异常,需要注意处理),对应的解析方法下面介绍。
parseByte 方法
public static byte parseByte(String s, int radix)
throws NumberFormatException {
int i = Integer.parseInt(s, radix);
if (i < MIN_VALUE || i > MAX_VALUE)
throw new NumberFormatException(
"Value out of range. Value:\"" + s + "\" Radix:" + radix);
return (byte)i;
}
传入字符串和进制数,调用了Integer.parseInt
方法获取转换后的整数,判断整数范围是否符合Byte
的范围。如果是,强制转换byte
类型返回;否,抛出NumberFormatException
异常。
public static byte parseByte(String s) throws NumberFormatException {
return parseByte(s, 10);
}
存在一个单参数的parseByte
方法,通过调用上面的方法实现,默认10进制数。
toString 方法
public static String toString(byte b) {
return Integer.toString((int)b, 10);
}
public String toString() {
return Integer.toString((int)value);
}
直接将byte
类型值强制转换成int
,然后调用了Integer.toString
方法进行操作。
valueOf 方法
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
对于byte
类型参数,直接通过计算偏移量,读取ByteCache
内部类的静态变量数组对应值来操作,提升了对应的空间和时间性能。
public static Byte valueOf(String s, int radix)
throws NumberFormatException {
return valueOf(parseByte(s, radix));
}
public static Byte valueOf(String s) throws NumberFormatException {
return valueOf(s, 10);
}
这两个方法是针对string
类型参数的,只是进制设定的问题。使用parseByte
方法将字符串转换成byte
类型值,然后直接使用第一个valueOf
方法操作。
decode 方法
public static Byte decode(String nm) throws NumberFormatException {
int i = Integer.decode(nm);
if (i < MIN_VALUE || i > MAX_VALUE)
throw new NumberFormatException(
"Value " + i + " out of range from input " + nm);
return valueOf((byte)i);
}
针对字符串解码,将字符串转换成Byte
类型值。主要逻辑是调用了Integer.decode
方法获取解码后的数字,然后判断对应返回是否符合byte
要求,调用valueOf
返回最终结果。
除去+/-
符号,会根据实际情况进行特定的解码,默认会处理成十进制。0x,0X,#
开头的会处理成16进制,0
开头的会处理成8进制。
xxxValue 方法
public byte byteValue() {
return value;
}
public short shortValue() {
return (short)value;
}
public int intValue() {
return (int)value;
}
public long longValue() {
return (long)value;
}
public float floatValue() {
return (float)value;
}
public double doubleValue() {
return (double)value;
}
通过强制类型转换,扩大了原有值类型范围,返回结果。
hashCode 方法
@Override
public int hashCode() {
return Byte.hashCode(value);
}
public static int hashCode(byte value) {
return (int)value;
}
直接返回了对应的int
类型值,作为其hashCode。
equals 方法
public boolean equals(Object obj) {
if (obj instanceof Byte) {
return value == ((Byte)obj).byteValue();
}
return false;
}
首先判断传入参数obj是不是Byte
的实例,是的话比较两者的值是否相等;否则直接返回false
。从这里可以看出来,我们在使用时也不需要对传入参数进行null == obj
的判断,可以忽略。
compare 方法
public static int compare(byte x, byte y) {
return x - y;
}
比较两者的值,x小于y时返回负数,x等于y时返回0,x大于y时返回正数。
compareTo 方法
public int compareTo(Byte anotherByte) {
return compare(this.value, anotherByte.value);
}
内部调用compare
方法。
toUnsignedInt 方法
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
将byte
转换成无符号整数。x强制转换成int
类型值,通过与0xff
进行位运算,保留低8位值,高24位设置成0。整体结果,0和正数保持不变,负数等于原来的值 + 2**8。
toUnsignedLong 方法
public static long toUnsignedLong(byte x) {
return ((long) x) & 0xffL;
}
过程同上,只是long
为64位,低8位保持原值,高56位设置成0。
总结
通过阅读源码发现,Byte
类大量使用了Integer
的方法,另外使用了内部类、位运算等方式进行了一定的逻辑优化。自己在看的过程对于内部类,补码,类的加载顺序也加深了了解,继续加油!