您的位置 首页 java

Java封神之路-拿下Byte

台上一分钟,台下十年功

每当看到资深工程师写代码或是分享自己的心得的时候,内心无比仰慕,惊叹大牛们为什么能把技术研究的如此之透彻。就好比,电视剧电影里,我们见过太多了武林高手一出场,那必定是能放出大招扭转乾坤,让人振奋不已。
但是坐下来静静想想,各个行业各路精英的每一次光彩绽放,背后应该都是有大量的练习和思考,这个过程并不那么光芒万丈,甚至还有些枯燥。
同样,如果想在 Java 这条路上封神,且不说封神,起码让自己对底层实现了解更加透彻,也是需要花费大量时间,下面就对今天看的内容做一个总结。主要看了java基本类库下的java.lang. byte

Byte

继承关系

Java封神之路-拿下Byte

可以看出,Byte继承了Number类,实现了Comparable接口

成员和方法:

Byte的取值范围从-128~127,为什么是这个区间,这是Java的基础。

小补充
概念: java中用补码表示 二进制 数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“1”表示负数。
正数补码为其本身;
负数补码为其绝对值各位取反加1;
例如:
+21,其二进制表示形式是00010101,则其补码同样为00010101
-21,按照概念其绝对值为00010101,各位取反为11101010,再加1为11101011,即-21的二进制表示形式为11101011
步骤:

  • byte为一字节8位,最高位是符号位,即最大值是01111111,因正数的补码是其本身,即此正数为01111111
    十进制表示形式为127

  • 最大正数是01111111,那么最小负是10000000(最大的负数是11111111,即-1)

  • 10000000是最小负数的补码表示形式,我们把补码计算步骤倒过来就即可。10000000减1得01111111然后取反10000000
    因为负数的补码是其绝对值取反,即10000000为最小负数的绝对值,而10000000的十进制表示是128,所以最小负数是-128

  • 由此可以得出byte的取值范围是-128到+127

    toString 方法

    public static String toString(byte b) {
     return Integer.toString((int)b, 10);
    } 

    该方法返回String类型的对象。默认将byte类型的参数强转为int类型,在10进制下的String类型的对象。

    内部静态类ByteCache

    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));
     }
    } 

    这个很有意思,这是将Byte的最小最大取值都装进一个Byte类型的 缓存 数组。
    静态初始化代码块在第一次类被加载的时候执行,可以看到通过遍历cache的长度,分别将-128到127共256个长度的数值塞入数组
    这个数组只会创建一次,后面每次使用都不用创建这个数组,这样做更加节省内存。
    这个ByteCache是如何调用的。下面我们看看valueOf方法

    valueOf方法

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

    该方法主要是返回一个byte类型对应的包装类型。
    写一个测试方法,看看valueOf方法是如何使用巧妙使用ByteCache的

    private static void testByte() {
     System.out.println(Byte.toString(Byte.MAX_VALUE));
     byte byteA = 1;
     byte byteB = 2;
     byte byteC = (byte)(byteA + byteB);
     System.out.println(Byte.valueOf(byteC));
    } 

    通过调试我们可以发现

  • 程序运行到Byte.valueOf方法后,内部就会调用ByteCache类的cache方法

  • 进入ByteCache类,会初始化一个 static final类型的cache数组

  • 在静态代码块中,为数组赋值
    当cache数组赋值完成,这时候我们看到数组大概张这样

Java封神之路-拿下Byte

  • 测试代码传入的参数是3,这时候在valueOf方法中会加入一个偏移量,因为cache数组是从0开始的,要想数组的下标和数组的值保持一致,需要加上偏移量128,[(int)b + offset]正好是131,而缓存数组cache[131]的值正好是3,所以返回Byte类型的3.

    小补充:这里为什么使用[(int)b + offset]而不是[b + offset]
    因为在Java中的byte,short,char进行计算时都会提升为int类型,所以这里需要强转为int类型。
    如果你写下面一段代码是不能编译通过的

    byte a = 1;
    byte b = 2;
    byte c= a + b; 

    这里写成这样就可以通过编译byte c = (byte)(a + b);(a + b)在相加的时候会自动提升为int,需要强转为byte再赋值给c。

    parseByte方法

    与Integer中的valueOf和parseInt存在调用关系不同,Byte中的valueOf并没有调用parseByte方法,而是直接使用了缓存数组。
    parseByte就是将String类型的字符转为byte基本类型,注意这里没有转为包装类型Byte。

    byteValue intValue longValue shortValue floatValue doubleValue

    作为一个byte返回该byte的值。这些方法都是继承自Number类。进入Number类,我们发现这里并没有booleanValue,charValue。
    因为进入Boolean和Character我们发现,这两个包装类都没有继承自Number。

文章来源:智云一二三科技

文章标题:Java封神之路-拿下Byte

文章地址:https://www.zhihuclub.com/193401.shtml

关于作者: 智云科技

热门文章

网站地图