JDK源码之Byte类分析
一 简介
byte,即字节,由8位的二进制组成。在Java中,byte类型的数据是8位带符号的二进制数,以二进制补码表示的整数
取值范围:默认值为0,最小值为-128(-27);最大值是127(27-1)
Byte类是byte的包装类,被final修饰,不能被继承,继承了Number类,可以用于数字类型的一系列转换,还实现了Comparable接口,可以用于比较
二 Number抽象类
Java 语言为每一个内置数据类型提供了对应的包装类。
Number类是java.lang包下的一个抽象类,提供了将包装类型拆箱成基本类型的方法,所有基本类型的数据包装类型都继承了该抽象类(除了Character、Boolean),并且是final声明不可继承改变
一般情况下我们会使用数据的基本数据类型:byte、int、short、long、double、float;
对应的包装类型:Byte、Integer、Short、Long、Double、Float; 每个包装类型都实现了所有类型转换的方法
该抽象类中定义方法都由子类去具体实现:
public abstract class Number implements java.io.Serializable {
public abstract int intValue();
public abstract long longValue();
public abstract float floatValue();
public abstract double doubleValue();
public byte byteValue() {
return (byte)intValue();
}
public short shortValue() {
return (short)intValue();
}
private static final long serialVersionUID = -8742448824652078965L;
}
三 源码分析
/**
* byte 最小值的常量 -2 ^ 7.
* Java 中用补码表示二进制数, 补码最高位表示符号位,0 表示正数,1 表示负数.
* 正数补码为其本身; 负数补码为其各位取反加1
*/
public static final byte MIN_VALUE = -128;
// byte 最大值为 2 ^ 7 -1
public static final byte MAX_VALUE = 127;
// Byte类型class实例
@SuppressWarnings("unchecked")
public static final Class<Byte> TYPE = (Class<Byte>) Class.getPrimitiveClass("byte");
public static String toString(byte b) {
return Integer.toString((int)b, 10);//按十进制数处理
}
//静态内部类,缓存使用
private static class ByteCache {
private ByteCache(){}
//缓存数组,长度为 128(负数) + 127(正数) + 1(0)
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
//缓存初始化,范围是-128到127
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128));
}
}
//推荐使用此方法进行构造Byte对象,从缓存中获取初始化好的Byte实例
@HotSpotIntrinsicCandidate
public static Byte valueOf(byte b) {
final int offset = 128;
return Byte.ByteCache.cache[(int)b + offset];
}
//解析字符串返回Byte包装类实例
public static Byte valueOf(String s) throws NumberFormatException {
return valueOf(s, 10);// 调用下面方法
}
//指定字符串进制数进行解析,返回包装类
public static Byte valueOf(String s, int radix)
throws NumberFormatException {
return valueOf(parseByte(s, radix));//调用下面方法
}
//解析String为byte基本类型,默认是十进制数
public static byte parseByte(String s) throws NumberFormatException {
return parseByte(s, 10);//调用下面方法
}
//将字符串解析为byte类型,radix是基数,radix是几,s就是几进制数,解析完结果是十进制数
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;
}
//可解析以0x,#或0前缀的十六进制八进制等等的数值,valueOf只支持十进制,基数默认写死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);
}
// Byte类型的基本数值
private final byte value;
//构造器: jdk9后已废弃(每次都会创建新的),推荐使用valueOf方法,(使用缓存,以节省性能)
@Deprecated(since="9")
public Byte(byte value) {
this.value = value;
}
@Deprecated(since="9")
public Byte(String s) throws NumberFormatException {
this.value = parseByte(s, 10);
}
/**
* 实现Number父类的数据类型方法,直接强转
*/
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;}
//调用Integer方法
public String toString() {
return Integer.toString((int)value);
}
//hash值为 value的int值
@Override
public int hashCode() {
return Byte.hashCode(value);
}
public static int hashCode(byte value) {
return (int)value;
}
//equals: 只有参数是Byte,并且byte值相等为true,其他为false
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;
} // 直接相减
// jdk9 新增,比较无符号的两个byte 大小
public static int compareUnsigned(byte x, byte y) {
return Byte.toUnsignedInt(x) - Byte.toUnsignedInt(y);
}
/**
* 0xff 表示为二进制就是 1111 1111。在byte类型中,代表-1(补码,除了符号位,其他取反再+1);但在short或者int类型中则代表255
* 当把byte类型的-1赋值到short或者int类型时(符号扩展),虽然值仍然代表-1,但却由1111 1111变成1111 1111 1111 1111.
* 再将其与0xff进行掩码:
* -1: 11111111 1111111
* 0xFF: 00000000 1111111
* 255: 00000000 1111111
* 所以这样,-1就转换成255.
*/
// jdk8新增,转换为无符号的int值需要零扩展而不是符号扩展
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
// jdk8新增,转换为无符号的long值
public static long toUnsignedLong(byte x) {
return ((long) x) & 0xffL;
}
// 位数, 8位
public static final int SIZE = 8;
// 字节数, byte 为 1
public static final int BYTES = SIZE / Byte.SIZE;
private static final long serialVersionUID = -7183698231559129828L;
JDK源码之Byte类分析的更多相关文章
- JDK源码之Integer类分析
一 简介 Integer是int基本类型的包装类,同样继承了Number类,实现了Comparable接口,String类中的一些转化方法就使用了Integer类中的一些API,且fianl修饰不可继 ...
- JDK源码之Boolean类分析
一 简介 boolean类型的封装类,将基本类型为boolean的值包装在一个对象中,实现序列化接口,和Comparable接口 额外提供了许多便捷方法,比较简单,直接贴代码分析 二 源码分析 //t ...
- JDK源码之AbstractStringBuilder类分析
一 概述 二 实现接口 AbstractStringBuilder实现了两个接口: Appendable 概述: Appendable的实现类的对象可以附加字符序列和值. 要追加的字符应该是Unico ...
- JDK源码之Double类&Float类分析
一 概述 Double 类是基本类型double的包装类,fainl修饰,在对象中包装了一个基本类型double的值.Double继承了Number抽象类,具有了转化为基本double类型的功能. 此 ...
- JDK源码之String类解析
一 概述 String由final修饰,是不可变类,即String对象也是不可变对象.这意味着当修改一个String对象的内容时,JVM不会改变原来的对象,而是生成一个新的String对象 主要考虑以 ...
- [Android FrameWork 6.0源码学习] LayoutInflater 类分析
LayoutInflater是用来解析XML布局文件,然后生成对象的ViewTree的工具类.是这个工具类的存在,才能让我们写起Layout来那么省劲. 我们接下来进去刨析,看看里边的奥秘 //调用i ...
- jdk源码理解-String类
String类的理解 简记录一下对于jdk的学习,做一下记录,会持续补充,不断学习,加油 1.String的hash值的计算方法. hash值的计算方法多种多样,jdk中String的计算方法如下,比 ...
- jdk源码阅读-Object类
native 关键字 private static native void registerNatives(); static { registerNatives(); } public final ...
- 深入JDK源码之Arrays类中的排序查找算法(转)
原文出处: 陶邦仁 binarySearch()方法 二分法查找算法,算法思想:当数据量很大适宜采用该方法.采用二分法查找时,数据需是排好序的. 基本思想:假设数据是按升序排序的,对于给定值x,从序列 ...
随机推荐
- Java并发编程系列-(8) JMM和底层实现原理
8. JMM和底层实现原理 8.1 线程间的通信与同步 线程之间的通信 线程的通信是指线程之间以何种机制来交换信息.在编程中,线程之间的通信机制有两种,共享内存和消息传递. 在共享内存的并发模型里,线 ...
- js对当前时间进行处理
//1.JS获取两个日期之间相差的天数 function getDaysBetween(dateString1, dateString2) { var startDate = Date.parse(d ...
- Redis事务、持久化、发布订阅
一.Redis事物 1. 概念 Redis 事务可以一次执行多个命令, 并且带有以下两个重要的保证: 事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他 ...
- 20191024-3 互评Alpha阶段作品
此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9860 本组对构建之法组评价的博客链接:https://www.cnblog ...
- 洛谷$P5038\ [SCOI2012]$奇怪的游戏 二分+网络流
正解:二分+网络流 解题报告: 传送门$QwQ$ 这种什么,"同时增加",长得就挺网络流的$QwQ$?然后看到问至少加多少次,于是考虑加个二分呗?于是就大体确定了做题方向,用的网络 ...
- java做插入时ID为自增获取到ID
<selectKey keyProperty="id" resultType="int" order="AFTER"> sele ...
- Windows To Go 企业版2019 LTSC 开发环境部署
Windows To Go 是一项非常实用的功能,与传统方式安装Windows 10相比更具有灵活性,会根据每次接入的硬件型号保留不同版本驱动. 由于博主是一名全栈程序员(截至发稿处于菜鸟级别),对灵 ...
- 小小知识点(三十)集中式大规模和无小区大规模MIMO
集中式大规模MIMO 同一小区的所有接入点( access point,AP) 布置在同一个基站( base station,BS) 中,并且 AP 之间的间距非常小,这种布置方式称为集中式大规模MI ...
- .Net PE
// ConsoleApplication26.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h& ...
- 【JavaScript学习笔记】函数、数组、日期
一.函数 一个函数应该只返回一种类型的值. 函数中有一个默认的数组变量arguments,存储着传入函数的所有参数. 为了使用函数参数方便,建议给参数起个名字. function fun1(obj, ...