声明: 此笔记本人通过观看【尚学堂】+(赖小平主编)清华大学出版社的《Java程序设计》感悟整理得出, 若有任何相关问题,请注明来源联系作者!
8.1 包装类
JAVA是面向对象的语言,但是我们经常用的基本数据类型就不是对象。但是我们经常需要将基本数据类型转化为对象。
为了解决这个问题,JAVA在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类。
包装类位于java.lang包,八种包装类和基本数据类型的对应关系如表:
基本数据类型 | 包装类 |
---|---|
byte | Byte |
boolean | Boolean |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
注:在八个类中,除了int、char不一样,其它类的类名和基本数据类型一致,只是首字母大写
在八类中,除了Boolean和Character以外,其它都是“数字型”,都是java.lang.Number的子类。Number类是抽象类,因此它有抽象方法,所有的子类都需要提供实现。Number类提供了抽象方法:intValue() 、longValue()、floatValue()、doubleValue(),意味着所有的“数字型”包装类都可以相互转型。
-
【图 Number的子类】
-
【图 Number类中的抽象方法】
-
【实例 测试包装类】
public class WrapperClassTest {
public static void main(String[] args) {
//把基本类型转化为包装类对象
Integer a = new Integer(20);
//官方写法,最好用这种方法写。其它基本类型同理!
Integer b = Integer.valueOf(20);
Double c = Double.valueOf(20.5);
//包装类对象转化为基本类型(父类Number类提供了转化的方法)
int back = b; //自动转化
int back01 = b.intValue(); //手动转化
//字符串转化为包装型对象(String型转化为基本类型的整型包装对象)
//两种方式(查看valueOf源码)
Integer change = Integer.valueOf("999999"); //"..",..要是数字(转化为整型包装类对象)
Integer change01 = Integer.parseInt("888888"); //不转化为10进制
Integer change02 = Integer.parseInt("888888",10);//转化为10进制
//包装类对象转回String类型
String back02 = change.toString();
//常量,其它类型的调用同理。输出最大值
System.out.println("int类型的最大整数:" + Integer.MAX_VALUE);
System.out.println("boolean类型的最大数值:" + Double.MAX_VALUE);
}
}
- 【多练!熟悉它们之间的转化】
8.2 包装类—自动装箱和拆箱
自动装箱:基本类型的数据自动转化为所需要的对象(如: Integer b = 5(JDK1.5之后才可以),能把基本数据类型转化为包装类对象,是因为JVM自动为我们执行了Integer b = Integer.valueOf(5);的操作,这就叫做自动装箱)
自动拆箱:当需要一个值时,对象自动转化为基本数据类型。(如 int back = b; 这样就实行的自动拆箱的功能,不需要再显式调用intValue();等方法)
- 【实例 测试自动装箱和拆箱】
public class TestWrapper {
public static void main(String[] args) {
//自动装箱,其实编译器会修改成:Integer a = Integer.valueOf(10);
Integer a = 10;
//自动拆箱,其实编译器会修改成:int b = a.intValue();
int b = a;
/*缓存问题(缓存[-128—127]之间的数字。)
* 查看valueOf的源码发现:系统初始化的时候创建了一个【-128—127】的缓存数组,
* 转为包装类对象时,如果基本类型(int型)的值在这个范围内,系统直接在缓存数组
* 中拿出创建好的对象;如果不在这个范围内则创建新对象!所以d1与d2指向不同的地址 */
Integer c1 = 10;
Integer c2 = 10;
System.out.println(c1==c2);
System.out.println(c1.equals(c2));
Integer d1 = 1234;
Integer d2 = 1234;
System.out.println(d1==d2);
System.out.println(d1.equals(d2));
}
}
- 【执行结果】
- 【按住Ctrl查看valueOf的源码】
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
- 【按住ctrl查看low源码】
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
static Integer[] archivedCache;
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
h = Math.max(parseInt(integerCacheHighPropValue), 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
注:由上述的源码可知系统初始化的时候创建了一个【-128—127】的缓存数组,也就是说
转为包装类对象时,如果基本类型(int型)的值在这个范围内,系统直接在缓存数组中拿出创建好的对象,使得它们的对象指向同一个地址;如果不在这个范围内则创建新对象!所以d1与d2指向不同的地址