剖析JDK源码-基本数据类型的装箱和拆箱 -(6)
java基本数据类型有:byte、short、int、long、float、double、boolean、char。
一、简述
- 变量的声明就是申请内存来存储值,但不同的数据占用的内存空间不同,为了让内存的使用更合理化,就有了数据类型的划分。(内存管理系统根据变量的类型为变量分配存储空间,分配的空间只能用来储存该类型数据。)
- 1个字节存储8位无符号数,除去符号位只有7位可用存储。
- 基本数据类型并不存在对象的特征,但java是面向对象编程的语言,所以为了配合万物皆可对象的原则,也对基本数据类型进行了封装。
数据类型名称 | 占字节 | 最大值 | 最小值 |
---|---|---|---|
byte | 1 | 127 | -128 |
short | 2 | 32767 | -32767 |
int | 4 | 2147483647 | 2147483648 |
long | 8 | 9223372036854774807 | -9223372036854774808 |
float | 4 | 1.401298e-45 | 3.402823e+38 |
double | 8 | 4.9000000e-324 | 1.797693e+308 |
char | 2 | \u0000 | uFFFF |
二、源码
1.整型(byte、short、int、long)
-这四个对象源码部分含有的属性都一样,只是对应的数值不同,一起介绍;而各自的内部方法实现有些差异,就分开讲解。
public final class T extends Number implements Comparable<T> {
@Native public static final t MIN_VALUE = ;
@Native public static final t MAX_VALUE = ;
public static final Class<T> TYPE = (Class<T>) Class.getPrimitiveClass("t");
}
private final t value;
public static final int SIZE = ;
public static final int BYTES = SIZE / Byte.SIZE;
- 继承了Number类。
- 实现Comparable泛型类。(实现比较的方法)
- 定义最大值和最小值。
- 定义对应的基本类型。
- 基本数据类型的属性值。
- 定义字节占用空间。
- 用于表示二进制补码二进制形式的 byte值的字节数。
2、Byte内部方法
- 返回一个新的 String对象,代表指定的 byte值。
- 返回当前Byte的String对象。
public static String toString(byte b) {
return Integer.toString((int)b, 10);
}
public String toString() {
return Integer.toString((int)value);
}
- 返回一个 Byte指定的 byte值的 Byte对象。定义offset=128,调用内部类ByteCache;传入参数赋值得到一个指定大小的数组cache[];
- valueOf(String s, int radix); 返回一个 Byte对象,该对象保存从指定的String中 String的值,并使用第二个参数给出的基数进行解析。
- 返回一个由指定的给定的值 String的 Byte对象 。
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
}
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 valueOf(String s, int radix)
throws NumberFormatException {
return valueOf(parseByte(s, radix));
}
public static Byte valueOf(String s) throws NumberFormatException {
return valueOf(s, 10);
}
- parseByte(String s);将字符串参数解析为带符号的十进制 byte 。
- parseByte(String s,int radix);将字符串参数的指定的基数解析为带符号的十进制 byte 。
public static byte parseByte(String s) throws NumberFormatException {
return parseByte(s, 10);
}
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 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;
}
- 返回当前对象或指定byte的哈希码,
@Override
public int hashCode() {
return Byte.hashCode(value);
}
public static int hashCode(byte value) {
return (int)value;
}
- 将此对象与指定的对象进行比较。instanceof(先检查传入的参数对象obj是否是Byte类型,否则直接返回false)
public boolean equals(Object obj) {
if (obj instanceof Byte) {
return value == ((Byte)obj).byteValue();
}
return false;
}
- 比较两个 Byte对象的值。
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;
}
3、Short 内部方法
- 返回一个值为short的 String对象。
- 返回一个当前Short的 String对象。
public static String toString(short s) {
return Integer.toString((int)s, 10);
}
public String toString() {
return Integer.toString((int)value);
}
- 将字符串参数解析为带符号的十进制 short 。
- 将字符串参数解析为由第二个参数指定的基数中的带符号的 short 。
public static short parseShort(String s) throws NumberFormatException {
return parseShort(s, 10);
}
public static short parseShort(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 (short)i;
}
- 返回一个 Short对象,保存从指定的String String的值,并用第二个参数给出的基数进行解析。
- 返回String 参数的Short对象。
- 返回表示 Short的 short值的 Short对象。
public static Short valueOf(String s, int radix)
throws NumberFormatException {
return valueOf(parseShort(s, radix));
}
public static Short valueOf(String s) throws NumberFormatException {
return valueOf(s, 10);
}
private static class ShortCache {
private ShortCache(){}
static final Short cache[] = new Short[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Short((short)(i - 128));
}
}
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
if (sAsInt >= -128 && sAsInt <= 127) { // must cache
return ShortCache.cache[sAsInt + offset];
}
return new Short(s);
}
- 进行强制转型
public byte byteValue() {
return (byte)value;
}
public short shortValue() {
return 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;
}
- 返回当前对象或指定short的哈希码;
@Override
public int hashCode() {
return Short.hashCode(value);
}
public static int hashCode(short value) {
return (int)value;
}
- 将此对象与指定的对象进行比较。instanceof(先检查传入的参数对象obj是否是Short类型,否则直接返回false)
public boolean equals(Object obj) {
if (obj instanceof Short) {
return value == ((Short)obj).shortValue();
}
return false;
}
- 比较值
public int compareTo(Short anotherShort) {
return compare(this.value, anotherShort.value);
}
public static int compare(short x, short y) {
return x - y;
}
- 返回反转指定的二进制补码表示的字节顺序而获得的值 short值。
public static short reverseBytes(short i) {
return (short) (((i & 0xFF00) >> 8) | (i << 8));
}
- 将参数无符号转换。
public static int toUnsignedInt(byte x) {
return ((int) x) & 0xff;
}
public static long toUnsignedLong(byte x) {
return ((long) x) & 0xffL;
}
4、Integer 内部方法
- 定义所有可能的字符
final static char[] digits = {
'0' , '1' , '2' , '3' , '4' , '5' ,
'6' , '7' , '8' , '9' , 'a' , 'b' ,
'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
'o' , 'p' , 'q' , 'r' , 's' , 't' ,
'u' , 'v' , 'w' , 'x' , 'y' , 'z'
};
- 返回由第二个参数指定的基数中的第一个参数的字符串表示形式。
- 返回一个 String指定整数的 String对象。(Byte和Short对象都调用了本方法)
public static String toString(int i, int radix) {
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
char buf[] = new char[33];
boolean negative = (i < 0);
int charPos = 32;
if (!negative) {
i = -i;
}
while (i <= -radix) {
buf[charPos--] = digits[-(i % radix)];
i = i / radix;
}
buf[charPos] = digits[-i];
if (negative) {
buf[--charPos] = '-';
}
return new String(buf, charPos, (33 - charPos));
}
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
getChars(i, size, buf);
return new String(buf, true);
}
- 以第二个参数指定的基数中的无符号整数值返回第一个参数的字符串表示形式。
- 将参数的字符串表示形式返回为无符号十进制值。
public static String toUnsignedString(int i, int radix) {
return Long.toUnsignedString(toUnsignedLong(i), radix);
}
public static String toUnsignedString(int i) {
return Long.toString(toUnsignedLong(i));
}
/**
- 略
**/
三、常见面试题
1、运行short s1 = 1; s1 = s1 + 1;会出现什么结果?
答:运行报错
short s1 = 1; s1 = s1 + 1;中,1 是int 型 s1 short型 通过 + 运算后s1 自动转为int 型 所以会报错。
2、同样的,运行short s1 = 1; s1 += 1;又会出现什么结果?
答:运行正常,打印s1会看到值为2
在实际项目中,+1是针对int类型的操作,如果可以,把short改成int。
3、"= ="和equals方法究竟有什么区别?
答:= =是比较地址,而在Object里的equals方法,也是判断地址是否一样,但在子类里,我们一般会重写equals方法,比如在String类里,equals方法则是判断值是否一致。
4、Integer与int的区别是什么。
答:Integer是封装类,其中包含了int基本数据类型和针对int的一些操作。而int是基本数据类型。
5、定义float 型的变量, float f=3.6是否正确?
答:不正确
精度不准确,应该用强制类型转换,如下所示:float f=(float)3.6 或float f = 3.6f