Java的Byte类主要的作用就是对基本类型byte进行封装,提供了一些处理byte类型的方法,比如byte到String类型的转换方法或String类型到byte类型的转换方法,当然也包含与其他类型之间的转换方法。

主要实现代码如下:

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

}

变量

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>
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层获取名称,

public String toString() {
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
            + getName();
    }

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

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异常。

    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方法一样。

    public Byte(byte value) {
        this.value = value;
    }

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

toString方法

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

    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的,避免重复的实例化和回收。

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对象即可。

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,因为后面的是十六进制,它会根据实际情况进行解码。

    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类型的值。

    public int hashCode() {
        return Byte.hashCode(value);
    }

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

equals方法

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

    public boolean equals(Object obj) {
        if (obj instanceof Byte) {
            return value == ((Byte)obj).byteValue();
        }
        return false;
    }

compare方法

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

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

无符号转换

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

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

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

以下是广告相关阅读

========广告时间========

鄙人的新书《Tomcat内核设计剖析》已经在京东销售了,有需要的朋友可以到 https://item.jd.com/12185360.html 进行预定。感谢各位朋友。

为什么写《Tomcat内核设计剖析》

=========================

相关阅读:

从JDK源码角度看Object

谈谈Java基础数据类型

从JDK源码角度看并发锁的优化

从JDK源码角度看线程的阻塞和唤醒

从JDK源码角度看并发竞争的超时

从JDK源码角度看java并发线程的中断

从JDK源码角度看Java并发的公平性

从JDK源码角度看java并发的原子性如何保证

从JDK源码角度看Boolean

欢迎关注:

从JDK源码角度看Byte的更多相关文章

  1. 从JDK源码角度看Short

    概况 Java的Short类主要的作用就是对基本类型short进行封装,提供了一些处理short类型的方法,比如short到String类型的转换方法或String类型到short类型的转换方法,当然 ...

  2. 从JDK源码角度看Boolean

    Java的Boolean类主要作用就是对基本类型boolean进行封装,提供了一些处理boolean类型的方法,比如String类型和boolean类型的转换. 主要实现源码如下: public fi ...

  3. 从JDK源码角度看Object

    Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...

  4. 从JDK源码角度看java并发的公平性

    JAVA为简化开发者开发提供了很多并发的工具,包括各种同步器,有了JDK我们只要学会简单使用类API即可.但这并不意味着不需要探索其具体的实现机制,本文从JDK源码角度简单讲讲并发时线程竞争的公平性. ...

  5. 从JDK源码角度看java并发的原子性如何保证

    JDK源码中,在研究AQS框架时,会发现很多地方都使用了CAS操作,在并发实现中CAS操作必须具备原子性,而且是硬件级别的原子性,java被隔离在硬件之上,明显力不从心,这时为了能直接操作操作系统层面 ...

  6. 从JDK源码角度看线程池原理

    "池"技术对我们来说是非常熟悉的一个概念,它的引入是为了在某些场景下提高系统某些关键节点性能,最典型的例子就是数据库连接池,JDBC是一种服务供应接口(SPI),具体的数据库连接实 ...

  7. 从JDK源码角度看并发竞争的超时

    JDK中的并发框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待 ...

  8. 从JDK源码角度看java并发线程的中断

    线程的定义给我们提供了并发执行多个任务的方式,大多数情况下我们会让每个任务都自行执行结束,这样能保证事务的一致性,但是有时我们希望在任务执行中取消任务,使线程停止.在java中要让线程安全.快速.可靠 ...

  9. 从 JDK 源码角度看 Object

    Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...

随机推荐

  1. 20145303刘俊谦 《Java程序设计》第4周学习总结

    20145303刘俊谦 <Java程序设计>第4周学习总结 教材学习内容总结 1.继承:继承是面向对象的第二大特征,避免多个类间重复定义共同行为.把单独抽取出来的那个类称为父类,其他的多个 ...

  2. 20145321 《Java程序设计》第9周学习总结

    20145321 <Java程序设计>第9周学习总结 教材学习内容总结 第十六章 整合数据库 16.1 JDBC 1.JDBC简介: JDBC是Java联机数据库的标准规范,它定义一组标准 ...

  3. android ramdisk

    android ramdisk 1.android文件系统的结构android源码编译后得到system.img,ramdisk.img,userdata.img映像文件.其中, ramdisk.im ...

  4. MapReduce实现共同朋友问题

    答案: package com.duking.mapreduce; import java.io.IOException; import java.util.Set; import java.util ...

  5. Hive的三种Join方式

    Hive的三种Join方式 hive Hive中就是把Map,Reduce的Join拿过来,通过SQL来表示. 参考链接:https://cwiki.apache.org/confluence/dis ...

  6. Android -- 文件上传到服务器

    1. 文件上传的两种方式 (1) HttpClient (2)AsyncHttpClient (开源框架: https://github.com/loopj/android-async-http) 示 ...

  7. Kettle 数据抽取

    1.创建数据库连接 2.建立转换 3.指定源数据库和目标数据库的字段映射 一定要在「输出」中勾选「指定字段」,然后点按钮「Get All fields」,再「Enter mapping」,在弹出窗口映 ...

  8. 数据可视化——matplotlib(3)

    导入相关模块 import matplotlib.pyplot as plt import numpy as np import pandas as pd 中文显示设置 在之前,绘图时均使用的是英文, ...

  9. webstorm的安装、激活码、更换主题颜色的修改、汉化

    一.安装 1.解压webstorm11zh.rar,双击.exe文件,下一步安装,在安装结束前会提示输入激活码,这个从网上随便找一个可用的即可. 二.更换主题颜色: 1.先从网上找一个喜欢的主题颜色, ...

  10. 【BZOJ3597】方伯伯运椰子(分数规划,网络流)

    [BZOJ3597]方伯伯运椰子(分数规划,网络流) 题解 给定了一个满流的费用流模型 如果要修改一条边,那么就必须满足流量平衡 也就是会修改一条某两点之间的路径上的所有边 同时还有另外一条路径会进行 ...