Java中泛型和包装类

目录

1. 泛型

1.1 泛型类的引用

1.2 泛型的定义

1.3 泛型背后作用时期和背后的简单原理

1.4 泛型类的使用

1.5 泛型的陷阱

1.6 泛型的意义

2. 包装类

2.1 基本数据类型和包装类直接的对应关系

2.2 包装类的使用,装箱(boxing)和拆箱(unboxing)


1. 泛型

1.1 泛型类的引用

问题:简单的顺序便只能够存放 int 数据,如果现在需要保存 指向 Person 类型对象的引用的顺序表,请问应该如何解决?如果又需要保存指向 Book 对象类型的引用呢?
回答:1. 首先,我们在学习多态过程中已知一个前提,基类的引用可以指向子类的对象。
           2. 其次,我们也已知 Object 是 java 中所有类的父类。
那么,要解决上述问题,我们很自然的想到一个解决办法,将我们的顺序表的元素类型定义成 Object 类型,这样
我们的 Object 类型的引用可以指向 Person 类型的对象或者指向 Book 类型的对象了

public class MyArrayList {
    private Object[] array; // 保存顺序表的元素,即 Object 类型的引用
    private int uesdSize; // 保存顺序表内数据个数
    public void add(Object o) { 尾插 }
    public Object get() { 获取最后位置的元素 }
...
}

遗留问题:现在的 MyArrayList 虽然可以做到添加任意类型的引用到其中了,但遇到以下代码就会产生问题

MyArrayList books = new MyArrayList();
books.add(new Book);
// 将 Object 类型转换为 Person 类型,需要类型转换才能成功
// 这里编译正确,但运行时会抛出异常 ClassCastException
Person person = (Person)books.get();

问题暴露的越早,影响越小。编译期间的问题只会让开发者感觉到,运行期间的错误会让所有的软件使用者
承受错误风险

所以我们需要一种机制,可以 1. 增加编译期间的类型检查 2. 取消类型转换的使用 泛型就此诞生!
 

1.2 泛型的定义

// 1. 尖括号 <> 是泛型的标志
// 2. T 是类型变量(Type Variable),变量名一般要大写
// 3. T 在定义时是形参,代表的意思是 MyArrayList 最终传入的类型,但现在还不知道                 
public class MyArrayList<T> {
    public T[] elems;
    public int usedSize;
    public MyArrayList() {
        //this.elems = new T[10];错误
        this.elems = (T[])new Object[10];
        this.usedSize = 0;
    }
    public void add(T data) {
        this.elems[this.usedSize] = data;
        this.usedSize++;
    }
    public T get() {
        return this.elems[this.usedSize-1];
    }
    ...
}

注意: 泛型类可以一次有多个类型变量,用逗号分割

MyArrayList是一个泛型类

<T>:T它只是一个占位符,标识当前类为泛型类

 

1.3 泛型背后作用时期和背后的简单原理

1. 泛型是作用在编译期间的一种机制,即运行期间没有泛型的概念。
2. 泛型代码在运行期间,就是我们上面提到的,利用 Object 达到的效果(这里不是很准确,以后会做说明)。

 

1.4 泛型类的使用

// 定义了一个元素是 Book 引用的 MyArrayList
MyArrayList<Book> books = new MyArrayList<Book>();
books.add(new Book());
// 会产生编译错误,Person 类型无法转换为 Book 类型
books.add(new Person());
// 不需要做类型转换
Book book = book.get();
// 不需要做类型转换
// 会产生编译错误,Book 类型无法转换为 Person 类型
Person person = book.get();

通过以上代码,我们可以看到泛型类的一个使用方式:只需要在所有类型后边跟尖括号,并且尖括号内是真正的类
型,即 T 可以看作的最后的类型。
注意: Book 只能想象成 T 的类型,但实际上 T 的类型还是 Object

1.5 泛型的陷阱

  • 泛型类型的参数不能是简单类型。一定要是对象的包装类
  • MyArrayList<int> myArrayList3 = new MyArrayList<>(); 错误
  • 不能够new一个泛型类型的数组T[] T[] elem = new T[10];
  • 泛型类型的参数不参与类型的组成

1.6 泛型的意义

1.可以进行自动类型检查

2.自动进行类型转换

2. 包装类

2.1 基本数据类型和包装类直接的对应关系

基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

基本上就是类型的首字母大写,除了 IntegerCharacter

2.2 包装类的使用,装箱(boxing)和拆箱(unboxing)

        //int -> Integer 自动装包/装箱
        Integer a = 10;
        System.out.println(a);
        //int -> Integer 手动装包/装箱
        Integer b = Integer.valueOf(20);
        int c = a;//自动拆包/拆箱     默认拆成整型:intValue
        double d = a.doubleValue();//手动拆包/拆箱       拆成double:doubleValue
        System.out.println(c);
        System.out.println(d);

注意:自动装箱和自动拆箱是工作在编译期间的一种机制
 

发布了20 篇原创文章 · 获赞 9 · 访问量 901

猜你喜欢

转载自blog.csdn.net/weixin_44915811/article/details/104174722