JDK源码阅读——java.lang.Byte

本文深入解析了Java中的Byte类,包括其内部实现、常用方法如valueOf、parseByte等的功能及使用方式,同时还介绍了Byte类的对象创建及数值转换方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Byte

1.概述

public final class Byte extends Number implements Comparable<Byte>
Byte 类将基本类型 byte 的值包装在一个对象中。一个 Byte 类型的对象只包含一个类型为 byte 的字段。
此外,该类还为 byte 和 String 的相互转换提供了几种方法,并提供了处理 byte 时非常有用的其他一些常量和方法。

2.UML类图

这里写图片描述

3.源码解析

public final class Byte extends Number implements Comparable<Byte> {
    public static final byte   MIN_VALUE = -128;
    public static final byte   MAX_VALUE = 127;

    /**
     *表示基本类型 byte 的 Class 实例。 
     */
    @SuppressWarnings("unchecked")
    public static final Class<Byte>     TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
    /**
    *返回表示此 Byte 的值的 String 对象。该值被转换成有符号的十进制表示形式,
    *并作为一个 string 返回,正如将 byte 值作为一个参数指定给 toString(byte) 方法所返回的一样。
    */
    public static String toString(byte b) {
        return Integer.toString((int)b, 10);
    }
    /**
    *内部私有静态类
    */
    private static class ByteCache {
    //私有化构造方法
        private ByteCache(){}
    //定义一个静态常量Byte数组,并初始化 大小256
        static final Byte cache[] = new Byte[-(-128) + 127 + 1];
    //静态代码块
        static {
        //为cache数组没有个元素赋值
            for(int i = 0; i < cache.length; i++)
                cache[i] = new Byte((byte)(i - 128));
        }
    }

    /**
     * 返回表示指定 byte 值的一个 Byte 实例。
     */
    public static Byte valueOf(byte b) {
        final int offset = 128;
        // ByteCache.cache[128]=0
        return ByteCache.cache[(int)b + offset];
    }

    /**
    * 将 string 参数解析为一个有符号的 byte,其基数由第二个参数指定。
    * 基数就是进制数 2<=radix<=36
    * 解析出来的数 -128<=i<=127
    */
    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;
    }

    /**
     * 将 string 参数解析为有符号的十进制 byte。
     */
    public static byte parseByte(String s) throws NumberFormatException {
        return parseByte(s, 10);
    }

    /**
     * 返回一个 Byte 对象,该对象保持从指定的 String 中提取的值,该值是在用第二个参数所给定的基数对指定字符串进行解析时提取的。
     */
    public static Byte valueOf(String s, int radix)
        throws NumberFormatException {
        return valueOf(parseByte(s, radix));
    }

    /**
     * 返回一个保持指定 String 所给出的值的 Byte 对象。
     */
    public static Byte valueOf(String s) throws NumberFormatException {
        return valueOf(s, 10);
    }

    /**
     * 将 String 解码为 Byte。
     * decode("33") = valueof("33",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);
    }


    private final byte value;

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

    public Byte(String s) throws NumberFormatException {
        this.value = parseByte(s, 10);
    }
    /**
    * 作为一个 byte 返回此 Byte 的值。
    */
    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;
    }

    /**
     * 通过无符号转换将参数转换为整数。
     * @since 1.8
     */
    public static int toUnsignedInt(byte x) {
        return ((int) x) & 0xff;
    }

    /**
     * 通过无符号转换将参数转换为long。
     * @since 1.8
     */
    public static long toUnsignedLong(byte x) {
        return ((long) x) & 0xffL;
    }

    /**
     * 用来表示于二进制补码形式的byte值的比特数
     * @since 1.5
     */
    public static final int SIZE = 8;
    /**
     *用来表示于二进制补码形式的byte值的字节数
     * @since 1.8
     */
    public static final int BYTES = SIZE / Byte.SIZE;

    /继承的Nubmer实现了java.io.Serializable/
    private static final long serialVersionUID = -7183698231559129828L;
}
### 解决 Java 程序中 `InaccessibleObjectException` 异常问题 #### 背景分析 该异常的根本原因在于 Java 平台模块系统(JPMS),自 Java 9 开始引入后,增强了封装性和安全性。默认情况下,某些核心包(如 `java.lang` 和 `java.util`)不会向未命名模块开放访问权限[^2]。 当程序尝试通过反射机制访问这些受保护的字段或方法时,如果目标模块没有显式声明对其开放,则会抛出 `java.lang.reflect.InaccessibleObjectException` 异常[^1]。 --- #### 解决方案 ##### 方法一:调整 JVM 启动参数 可以通过在启动命令中添加特定的 VM 参数来解决问题。以下是常用的解决方案: ```bash --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED ``` 这两个选项的作用是分别打开 `java.base` 模块中的 `java.lang` 和 `java.util` 包给未命名模块访问。对于更复杂的场景,可能还需要额外指定其他受影响的包,例如 `sun.net.util` 或 `sun.security.util`[^3]。 示例完整的启动命令如下: ```bash java --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.util=ALL-UNNAMED \ -jar your-application.jar ``` --- ##### 方法二:修改代码逻辑以避免反射调用 如果条件允许,建议重新设计代码逻辑,减少对私有字段或方法的直接访问需求。例如,在处理字符串操作时,尽量利用官方推荐的标准 API 替代反射方式。 具体实现取决于实际业务需求,但通常可以从以下几个方面入手: - 使用公开接口替代内部实现细节。 - 避免硬编码依赖于 JDK 的私有类或字段。 这种方法虽然需要更多时间重构现有代码,但从长远来看能够提高应用兼容性和可维护性[^2]。 --- ##### 方法三:降级至较低版本 JDK 作为临时措施之一,可以选择回退到较旧版本的 JDK(如 JDK 8)。因为在早期版本中并未启用 JPMS 制约规则,因此不会遇到此类限制[^1]。 然而需要注意的是,长期维持低版本环境可能会带来安全风险以及失去新特性支持等问题,故仅适用于短期过渡阶段。 --- #### 示例代码片段 假设存在一段引发此异常的代码如下所示: ```java Field valueField = String.class.getDeclaredField("value"); valueField.setAccessible(true); // 这里触发 InaccessibleObjectException char[] value = (char[]) valueField.get(someString); ``` 针对上述情况可通过以下两种方式进行修正: ###### 方案 A – 修改 JVM 参数 按照前述说明设置合适的 `--add-opens` 参数即可正常运行而无需更改源码。 ###### 方案 B – 改写代码逻辑 替换掉原始反射部分并采用标准库函数完成相同功能: ```java // 原先做法可能导致异常 Field valueField = String.class.getDeclaredField("value"); // 新的做法完全规避了潜在隐患 public static char[] getStringValue(String str) { return str.toCharArray(); // 更加简洁明了且无安全隐患 } ``` --- ### 总结 综上所述,面对因 JPMS 封装策略所引起的 `InaccessibleObjectException` 错误,优先考虑适配最新规范并通过合理配置 JVM 参数快速定位修复;同时也要注重优化自身项目架构逐步淘汰不合规的操作手法从而彻底杜绝同类事件再次发生。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值