目录
1. 包装类
1.1 基本数据类型和对应的包装类
| 基本数据类型 | 包装类 |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
| boolean | Boolean |
总结:除Integer和Character以外,其他都是基本数据类型首字母大写。
1.2 装箱和拆箱机制
我们称数据从包装类的引用数据类型转化为基本数据类型叫做装箱。反之,则称之为拆箱。
int i = 10;
// 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer ii = Integer.valueOf(i);
Integer ij = new Integer(i);
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int j = ii.intValue();
可以看到在使用过程中,装箱和拆箱带来不少的代码量,所以为了减少开发者的负担,java 提供了自动机制。
int i = 10;
Integer ii = i; // 自动装箱
Integer ij = (Integer)i; // 自动装箱
int j = ii; // 自动拆箱
int k = (int)ii; // 自动拆箱
到这让我们看一组代码:

结果:

可以看到在c==d出现了问题,尽管两个数据数值相等,但它们输出的结果却不尽相同。
此时,我们猜想这应该与Integer的内部机制有关,那么就让我们来看看它内部的源码是如何实现的!


由上图可知:Interger传入的值i处于【low,high】的取值范围内,即【-128,127】。而第一张图中的vlueOf的逻辑便是当i处于范围内便去数组取值,不在范围内,则实例化一个新的对象,
因此,在c == d的比较中就相当于变成了两个引用类型的比较,这时,比较的是数据的地址位置,那自然是不相等的。
2. 泛型
2.1 什么是泛型
一般的类和方法,只能使用具体的类型: 要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的 代码,这种刻板的限制对代码的束缚就会很大。
----- 来源《Java编程思想》对泛型的介绍。
泛型是在JDK1.5引入的新的语法,通俗讲,泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数化。
2.2 泛型的引入
代码示例:
class MyArray {
public Object[] array = new Object[10];
public Object getPos(int pos) {
return this.array[pos];
}
public void setVal(int pos,Object val) {
this.array[pos] = val;
}
} public class TestDemo {
public static void main(String[] args) {
MyArray myArray = new MyArray();
myArray.setVal(0,10);
myArray.setVal(1,"hello");//字符串也可以存放
String ret = myArray.getPos(1);//编译报错
System.out.println(ret);
}
}
问题:以上代码实现后 发现:
1. 任何类型数据都可以存放
2. 1号下标本身就是字符串,但是确编译报错。必须进行强制类型转换
所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译器去做检查。
2.3 泛型的语法结构
class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> {
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使用部分类型参数
}
泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
2.4 泛型的使用
示例:
MyArray list = new MyArray();
注意:泛型只能接受类,所有的基本数据类型必须使用包装类!
2.5 泛型的上界
class 泛型类名称<类型形参 extends 类型边界> {
...
}
示例:
public class MyArray<E extends Number> {
...
}
只接受 Number 的子类型作为 E 的类型实参
MyArray l1; // 正常,因为 Integer 是 Number 的子类型
MyArray l2; // 编译错误,因为 String 不是 Number 的子类型
2.6 泛型的方法
2.6.1 语法
方法限定符 返回值类型 方法名称(形参列表) { ... }
2.6.2 示例
public class Util {
//静态的泛型方法 需要在static后用<>声明泛型类型参数
public static <E> void swap(E[] array, int i, int j) {
E t = array[i];
array[i] = array[j];
array[j] = t;
}
}
2.6.3 可以使用类型推导
Integer[] a = { ... };
swap(a, 0, 9);
String[] b = { ... };
swap(b, 0, 9);
2.6.4 不使用类型推导
Integer[] a = { ... };
Util.<Integer>swap(a, 0, 9);
String[] b = { ... };
Util.<String>swap(b, 0, 9);
本文详细介绍了Java中的包装类,包括基本数据类型及其对应的包装类,以及装箱和拆箱机制。此外,文章深入探讨了泛型的概念、使用、语法结构和方法,展示了泛型如何提高代码的灵活性和类型安全性。
1083





