从JDK源码角度看Byte

Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型之间的转换方法。
主要实现代码如下:
[Java] 纯文本查看 复制代码
?
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
public final class Byte extends Number implements Comparable<Byte> {
 
        public static final byte   MIN_VALUE = -128;
 
        public static final byte   MAX_VALUE = 127;
 
        public static final int SIZE = 8;
 
        public static final int BYTES = SIZE / Byte.SIZE;
 
        private final byte value;
 
        public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
 
        public Byte(byte value) {
            this.value = value;
        }
 
        public Byte(String s) throws NumberFormatException {
            this.value = parseByte(s, 10);
        }
 
        public static String toString(byte b) {
            return Integer.toString((int)b, 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));
            }
        }
 
        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;
        }
 
        public static byte parseByte(String s) throws NumberFormatException {
            return parseByte(s, 10);
        }
 
        public static Byte valueOf(byte b) {
            final int offset = 128;
            return ByteCache.cache[(int)b + offset];
        }
 
        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);
        }
 
        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);
        }
 
        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;
        }
 
        public String toString() {
            return Integer.toString((int)value);
        }
 
        public int hashCode() {
            return Byte.hashCode(value);
        }
 
        public static int hashCode(byte value) {
            return (int)value;
        }
 
        public boolean equals(Object obj) {
            if (obj instanceof Byte) {
                return value == ((Byte)obj).byteValue();
            }
            return false;
        }
 
        public int compareTo(Byte anotherByte) {
            return compare(this.value, anotherByte.value);
        }
 
        public static int compare(byte x, byte y) {
            return x - y;
        }
 
        public static int toUnsignedInt(byte x) {
            return ((int) x) & 0xff;
        }
 
        public static long toUnsignedLong(byte x) {
            return ((long) x) & 0xffL;
        }
 
 
    }

变量

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
public static final byte   MIN_VALUE = -128;
   public static final byte   MAX_VALUE = 127;
   public static final int SIZE = 8;
   public static final int BYTES = SIZE / Byte.SIZE;
   private final byte value;
   public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
  • MIN_VALUE静态变量表示byte能取的最小值,值为-128,被final修饰说明不可变;
  • 类似的还有MAX_VALUE,表示byte的最大值为127。
  • SIZE用来表示于二进制补码形式的byte值的比特数,值为8,静态变量且不可变。
  • BYTES用来表示于二进制补码形式的byte值的字节数,值为1,静态变量且不可变。
  • 由于是对byte的封装,所以必定要有一个变量来保存byte的值,即value,同样它也被final修饰说明不可变。
  • TYPE的toString的值是byte。
    Class的getPrimitiveClass是一个native方法,在Class.c中有个Java_java_lang_Class_getPrimitiveClass方法与之对应,所以JVM层面会通过JVM_FindPrimitiveClass函数会根据”byte”字符串获得jclass,最终到Java层则为Class<Byte>。
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
JNIEXPORT jclass JNICALL
    Java_java_lang_Class_getPrimitiveClass(JNIEnv *env,
                                           jclass cls,
                                           jstring name)
    {
        const char *utfName;
        jclass result;
 
        if (name == NULL) {
            JNU_ThrowNullPointerException(env, 0);
            return NULL;
        }
 
        utfName = (*env)->GetStringUTFChars(env, name, 0);
        if (utfName == 0)
            return NULL;
 
        result = JVM_FindPrimitiveClass(env, utfName);
 
        (*env)->ReleaseStringUTFChars(env, name, utfName);
 
        return result;
    }



TYPE执行toString时,逻辑如下,则其实是getName函数决定其值,getName通过native方法getName0从JVM层获取名称,

[Java] 纯文本查看 复制代码
?
1
2
3
4
public String toString() {
            return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
                + getName();
        }


getName0根据一个数组获得对应的名称,JVM根据Java层的Class可得到对应类型的数组下标,比如这里下标为8,则名称为”byte”。

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
const char* type2name_tab[T_CONFLICT+1] = {
      NULL, NULL, NULL, NULL,
      "boolean",
      "char",
      "float",
      "double",
      "byte",
      "short",
      "int",
      "long",
      "object",
      "array",
      "void",
      "*address*",
      "*narrowoop*",
      "*conflict*"
    };


parseByte方法两个parseByte方法,主要看第一个即可,第一个参数是待转换的字符串,第二个参数表示进制数,这里的转换其实是调了Integer的parseInt方法,返回值再判断是不是在byte的最小值和最大值之间。怎么更好理解这个参数呢?举个例子,Byte.parseByte("100",10)表示十进制的100,所以值为100,而Byte.parseByte("100",2)表示二进制的100,所以值为4。另外如果Byte.parseByte("1000",10)会抛出java.lang.NumberFormatException异常。

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
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;
        }
 
        public static byte parseByte(String s) throws NumberFormatException {
            return parseByte(s, 10);
        }


构造函数
包含两种构造函数,分别可以传入byte和String类型。它是通过调用parseByte方法进行转换的,所以转换逻辑与上面的parseByte方法一样。

[Java] 纯文本查看 复制代码
?
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);
        }


toString方法
一个是静态方法一个是非静态方法,但两个方法转换的效果是一样的,都是以十进制形式转换。

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
public static String toString(byte b) {
            return Integer.toString((int)b, 10);
        }
        public String toString() {
            return Integer.toString((int)value);
        }


ByteCache内部类
ByteCache是Byte的一个内部类,它其实就是一个包含了byte所有可能值的Byte数组,对于byte来说其实它的可能值就是从-128到127,一共256个,所以我们只需要实例化256个Byte对象就可以表示所有可能的byte。而且这些都是静态且final的,避免重复的实例化和回收。

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
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));
            }
        }


valueOf方法
有三个valueOf方法,主要看下面这个,因为ByteCache包含了所有byte可能值的Byte对象,直接从ByteCache的数组中获取对应的Byte对象即可。

[Java] 纯文本查看 复制代码
?
1
2
3
4
public static Byte valueOf(byte b) {
        final int offset = 128;
        return ByteCache.cache[(int)b + offset];
    }


decode方法
decode方法主要作用是解码字符串转成Byte型,比如Byte.decode("11")的结果为11,而Byte.decode("0x11")结果为17,因为后面的是十六进制,它会根据实际情况进行解码。

[Java] 纯文本查看 复制代码
?
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);
        }


xxxValue方法
包括shortValue、intValue、longValue、floatValue和doubleValue等方法,其实就是转换成对应的类型。
hashCode方法
hashCode方法很简单,就是直接返回int类型的值。

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
7
public int hashCode() {
            return Byte.hashCode(value);
        }
 
        public static int hashCode(byte value) {
            return (int)value;
        }


equals方法
比较是否相同时先判断是不是Byte类型再比较值。

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
public boolean equals(Object obj) {
            if (obj instanceof Byte) {
                return value == ((Byte)obj).byteValue();
            }
            return false;
        }


compare方法
通过相减来比较,大于0则说明x大于y。

[Java] 纯文本查看 复制代码
?
1
2
3
public static int compare(byte x, byte y) {
            return x - y;
        }


无符号转换
包括转成无符号int型和无符号long型。

[Java] 纯文本查看 复制代码
?
1
2
3
4
5
6
7
public static int toUnsignedInt(byte x) {
            return ((int) x) & 0xff;
        }
 
        public static long toUnsignedLong(byte x) {
            return ((long) x) & 0xffL;
        }

更多学习资料可关注gzitcast获取(weiixn)

发布了765 篇原创文章 · 获赞 3 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u010395024/article/details/104914359