这次我们来看看Byte类的源代码,基于 jdk1.8.0_181.jdk 版本 。

概要

Java的Byte类主要是对byte基本数据类型的封装,有着一个字段存放着对应的byte数据值,另外提供了一些方法方便对byte进行相关的操作。

类定义

1
public final class Byte extends Number implements Comparable<Byte>

Byte类带有关键字final,也就是不可以继承的,另外继承了Number类,实现了Comparable接口,也就是可以进行比较。

属性

1
2
3
public static final byte   MIN_VALUE = -128;

public static final byte   MAX_VALUE = 127;

定义了Byte的范围大小,由于补码的关系,负数会比正数多一个值,MIN_VALUE能取的值为 -2**8,而MAX_VALUE能取的值为2**8 - 1,具体原码和补码的逻辑,可以参考下原码、反码、补码的产生、应用以及优缺点有哪些? - 知乎用户的回答 - 知乎,个人觉得讲解的不错。

1
public static final int SIZE = 8;

定义了byte值的二进制补码格式的bit位数,固定8位。

1
public static final int BYTES = SIZE / Byte.SIZE;

定义了byte值的二进制补码格式的字节数,计算值固定为1。

1
2
@SuppressWarnings("unchecked")
public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");

获取Byte的类信息,Byte.TYPE == byte.class,两者是等价的。

1
private final byte value;

Byte因为是byte的包装类,所以这里包含了对应的byte基本类型数据的变量。

1
private static final long serialVersionUID = -7183698231559129828L;

内部类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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 进行进一步的了解学习。

方法

构造方法

1
2
3
4
5
6
7
public Byte(byte value) {
  this.value = value;
}

public Byte(String s) throws NumberFormatException {
  this.value = parseByte(s, 10);
}

存在两个对应的构造方法,一个传入byte值,一个是传入字符串解析,转换成10进制整数处理(注意的是这个方法可能会抛出异常,需要注意处理),对应的解析方法下面介绍。

parseByte 方法

1
2
3
4
5
6
7
8
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异常。

1
2
3
public static byte parseByte(String s) throws NumberFormatException {
  return parseByte(s, 10);
}

存在一个单参数的parseByte方法,通过调用上面的方法实现,默认10进制数。

toString 方法

1
2
3
4
5
6
7
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 方法

1
2
3
4
public static Byte valueOf(byte b) {
  final int offset = 128;
  return ByteCache.cache[(int)b + offset];
}

对于byte类型参数,直接通过计算偏移量,读取ByteCache内部类的静态变量数组对应值来操作,提升了对应的空间和时间性能。

1
2
3
4
5
6
7
8
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 方法

1
2
3
4
5
6
7
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 方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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 方法

1
2
3
4
5
6
7
8
@Override
public int hashCode() {
  return Byte.hashCode(value);
}

public static int hashCode(byte value) {
  return (int)value;
}

直接返回了对应的int类型值,作为其hashCode。

equals 方法

1
2
3
4
5
6
public boolean equals(Object obj) {
  if (obj instanceof Byte) {
    return value == ((Byte)obj).byteValue();
  }
  return false;
}

首先判断传入参数obj是不是Byte的实例,是的话比较两者的值是否相等;否则直接返回false。从这里可以看出来,我们在使用时也不需要对传入参数进行null == obj的判断,可以忽略。

compare 方法

1
2
3
public static int compare(byte x, byte y) {
  return x - y;
}

比较两者的值,x小于y时返回负数,x等于y时返回0,x大于y时返回正数。

compareTo 方法

1
2
3
public int compareTo(Byte anotherByte) {
  return compare(this.value, anotherByte.value);
}

内部调用compare方法。

toUnsignedInt 方法

1
2
3
public static int toUnsignedInt(byte x) {
  return ((int) x) & 0xff;
}

byte转换成无符号整数。x强制转换成int类型值,通过与0xff进行位运算,保留低8位值,高24位设置成0。整体结果,0和正数保持不变,负数等于原来的值 + 2**8。

toUnsignedLong 方法

1
2
3
public static long toUnsignedLong(byte x) {
  return ((long) x) & 0xffL;
}

过程同上,只是long为64位,低8位保持原值,高56位设置成0。

总结

通过阅读源码发现,Byte类大量使用了Integer的方法,另外使用了内部类、位运算等方式进行了一定的逻辑优化。自己在看的过程对于内部类,补码,类的加载顺序也加深了了解,继续加油!