包装类型与泛型体系
- 包装类型
- 类型转换机制
- 泛型系统
- 泛型基础
- 泛型应用
- 类型边界控制
- 通配符体系
- 通配符原理
- 上限通配符
- 下限通配符
引言
Java语言中,原始数据类型并非Object类的子类。为了在泛型体系中兼容基础类型,Java为每种基本类型设计了对应的包装类。某些场景下必须通过泛型才能实现特定功能
包装类型系统
基础类型 | 对应包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
除int和char对应的Integer与Character外,其他包装类均为基础类型首字母大写形式 | |
### 类型转换过程 |
public class Demo {
public static void main(String[] args) {
int num = 20;
// 包装过程
Integer num1 = Integer.valueOf(num);
Integer num2 = new Integer(num);
// 解包过程
int x = num1.intValue();
int y = num2.intValue();
System.out.println(num1);
System.out.println(num2);
System.out.println(x);
System.out.println(y);
}
}
执行效果展示
传统转换方式需要调用特定方法,导致代码冗余
智能转换机制
public class Demo {
public static void main(String[] args) {
int num = 20;
Integer num1 = (Integer) num; // 显式转换
Integer num2 = num; // 隐式转换
int num3 = num1; // 自动解包
int num4 = (int) num2; // 强制解包
System.out.println(num1);
System.out.println(num2);
System.out.println(num3);
System.out.println(num4);
}
}
Java提供了自动转换机制
执行效果展示
基础类型与包装类型存在本质差异
public class Demo {
public static void main(String[] args) {
Integer val1 = 100;
Integer val2 = 100;
Integer val3 = 200;
Integer val4 = 200;
System.out.println(val1==val2);
System.out.println(val3==val4);
}
}
执行效果展示
此现象源于自动调用的Integer.valueOf方法
若使用基本类型比较将得到true,但包装类型比较结果不同,原因在于:
当数值在[-128,127]范围内时从缓存数组获取,否则创建新对象,因此超出范围的对象地址不同
泛型体系
泛型基本原理
传统方法受限于单一数据类型,泛型实现了多类型支持。我们可以创建通用容器:
class CustomArray{
private Object[] elements = new Object[10];
public Object getElement(int pos){
return elements[pos];
}
public void setElement(int pos, Object val){
this.elements[pos] = val;
}
}
public class Demo {
public static void main(String[] args) {
CustomArray arr = new CustomArray();
arr.setElement(0,100);
System.out.println(arr.getElement(0));
}
}
执行效果展示
但容器一旦确定元素类型后不可混用
泛型实践应用
泛型类定义
class GenericClass {
}
多类型支持:
class MultiTypeClass {
}
使用规范
GenericClass var = new GenericClass<>();
例如:
ArrayList numbers = new ArrayList<>();
类型参数可自动推导
改进后的实现:
class GenericArray{
private Object[] elements = new Object[10];
public T getElement(int pos){
return (T)elements[pos];
}
public void setElement(int pos, T val){
this.elements[pos] = val;
}
}
public class Demo {
public static void main(String[] args) {
GenericArray array = new GenericArray<>();
array.setElement(0,100);
System.out.println(array.getElement(0));
}
}
类型确定后不可变更
1. 基本类型不被支持
2. 类型一致性要求
泛型交换方法
public class Demo {
public static void main(String[] args) {
Integer[] data ={10,20,30};
swap(data,0,2);
}
public static void swap(T[] arr, int i, int j){
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
类型声明不可省略
1.类声明中的表示类型占位符
常见约定:E-元素, K-键, V-值, N-数字, T-类型
2.实例化时确定具体类型,仅支持包装类型
3.类型确定后不可混用其他类型
类型边界控制
泛型类型约束:
class GenericClass {
...
}
示例:
public class NumberCollection {
...
}
实现示例:
class NumberContainer{
private Object[] elements = new Object[10];
public T getElement(int pos){
return (T)elements[pos];
}
public void setElement(int pos, T val){
this.elements[pos] = val;
}
}
限定为数值类型:
public class Demo {
public static void main(String[] args) {
NumberContainer intContainer = new NumberContainer<>();
NumberContainer doubleContainer = new NumberContainer<>();
}
}
非数值类型将报错
通配符系统
通配符基础
?符号在泛型中的应用:
class MessageContainer{
private T content;
public T getContent() {
return content;
}
public void setContent(T content) {
this.content = content;
}
}
public class Demo {
public static void main(String[] args) {
MessageContainer msg = new MessageContainer<>();
msg.setContent("测试消息");
printContent(msg);
}
public static void printContent(MessageContainer msg){
System.out.println(msg.getContent());
}
}
执行效果展示
仅支持String类型
通配符解决方案:
public class Demo {
public static void main(String[] args) {
MessageContainer strMsg = new MessageContainer<>();
strMsg.setContent("文本消息");
printContent(strMsg);
MessageContainer intMsg = new MessageContainer<>();
intMsg.setContent(12345);
printContent(intMsg);
}
public static void printContent(MessageContainer msg){
System.out.println(msg.getContent());
}
}
执行效果展示
上限通配符
定义食品类体系
class Food{}
class Fruit extends Food{}
class Banana extends Fruit{}
class Apple extends Fruit{}
class FoodContainer{
private T item;
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
}
public class Demo {
public static void main(String[] args) {
FoodContainer fruitBox = new FoodContainer<>();
fruitBox.setItem(new Apple());
displayContent(fruitBox);
FoodContainer bananaBox = new FoodContainer<>();
bananaBox.setItem(new Banana());
displayContent(bananaBox);
}
public static void displayContent(FoodContainer container){
System.out.println(container.getItem());
}
}
执行效果展示
仅接受Fruit及其子类
不可添加不确定类型元素
下限通配符
继续使用食品类体系:
public class Demo {
public static void main(String[] args) {
FoodContainer fruitHolder = new FoodContainer<>();
fruitHolder.setItem(new Fruit());
processItem(fruitHolder);
FoodContainer foodHolder = new FoodContainer<>();
foodHolder.setItem(new Food());
processItem(foodHolder);
}
public static void processItem(FoodContainer holder){
System.out.println(holder.getItem());
}
}
执行效果展示
不接受子类类型
可添加子类元素但不可接收:
public static void processItem(FoodContainer holder){
holder.setItem(new Apple());
holder.setItem(new Banana());
System.out.println(holder.getItem());
}
类型不确定导致接收异常
至此完成主要内容讲解,后续内容将在后续章节展开
相关文章
暂无评论...