简单介绍-泛型和包装类数据结构

Posted 一朵花花

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单介绍-泛型和包装类数据结构相关的知识,希望对你有一定的参考价值。

泛型

什么是泛型?

背景:为了能够写一个类 / 一个方法,就能够同时支持多种不同类型的对象

所谓的泛型,就是从语法层面对 Object 进行了一个简单的包装,编译过程可以帮我们自动加上一些编译期的类型检查,自动帮我们完成一些类型转换工作

举例:

ArrayList 就是一个泛型的实例,可以聚集任何类型的对象

使用 Object,因为在 Java 中,Object 是所有子类直接 / 间接继承的父类

public class ArrayListTest {
    private Object[] data;
}

public class ArrayListTest {
    private Object[] data;
    private Object[] data = new Object[20];
	private int size;

	public void add(Object elem){
   		data[size] = elem;
    	size++;
	}

	public Object get(int index){
    	return data[index];
	}
}

上述代码在运用时,会出现问题,例:


String 继承 Object,
在调用 add 时,相当于向上转型,发生隐式类型转换
调用 get 时,返回 Object,但此时赋值给 String,此处为向下转型

可以使用泛型解决上述问题:

public class ArrayListTest<E> {
//当前这个 data 的类型,可以就当成一个 Object[ ]
//Object 具体代表的是哪种类型 需要最终在实例化 ArrayListTest 时,才能确定
    private E[] data = (E[])new Object[20];
    private int size;

    public void add(E elem){
        data[size] = elem;
        size++;
    }

    public E get(int index){
        return data[index];
    }

    public static void main(String[] args) {
        ArrayListTest<String> test = new ArrayListTest<>();
        test.add("Java");
        test.add("Cpp");
        String s = test.get(0);
    }
}

泛型编程,类似于一个"模板"

泛型参数只能是 引用类型



此时,再调用 add,就会发现,已经是 String 类型了

再例如
自己写一个 Animal 类:

public class Animal {
    private String name;
}
public class ArrayListTest<E> {
    private E[] data = (E[])new Object[20];
    private int size;

    public void add(E elem){
        data[size] = elem;
        size++;
    }

    public E get(int index){
        return data[index];
    }

    public static void main(String[] args) {
		ArrayListTest<Animal> animals = new ArrayListTest<>();
        animals.add(new Animal());
        Animal animal = animals.get(0);
    }
}

animals 调用 add 方法时,就会发现类型是 Animal


类型参数可以给编译器提供了很好的有效信息,当调用方法时,不需要进行强制类型转换,编译器就知道返回类型

泛型这样的语法是一种编译期的机制,为了方便程序猿书写代码,以及编译过程进行一些类型检查,编译完成了之后,在运行过程中,是没有泛型的
编译代码过程中,直接把泛型参数当成了 Object,只不过编译器自动加上了一些类型转换操作,以及类型校验操作

包装类

思考:如果是 int,double,等基础类型,如何套用泛型?

以 int 为例: 创建一个类,用这个类来表示一个整数
(标准库已经帮我们创建好了对应的类,就成为包装类)

包装类,就是把 8 种基础类型,用一个类稍微包装了一下,变成了引用类型

基本数据类型与其对应的包装类

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean
public static void main(String[] args) {
    ArrayListTest<Integer> list = new ArrayListTest<>();
	list.add(new Integer(66));
}

装箱(boxing):

将内置类型转换为包装类,称为装箱

手动装箱:

public static void main(String[] args) {
    ArrayListTest<Integer> list = new ArrayListTest<>();
    //把 int 转换成 Integer
    //1.
	Integer num1 = new Integer(66);  //装箱
	list.add(num1);
	//2.
	Integer num2 = Integer.valueOf(88);
	list.add(num2);
}

自动装箱:

编译器赋予包装类的特殊功能

Integer num3 = 10;

valueOf 是 Integer 类里的一个静态方法,通过 类名.方法名,即可调用

拆箱(unboxing):

手动拆箱:

Integer num = 10;
//拆箱
num = list.get(0);
int value2 = num.intValue();

自动拆箱:

Integer num = 10;
int value = num;

所谓的 装 / 拆箱,就是类型转换
所谓的 自动拆 / 装箱,就是隐式类型转换

以上是关于简单介绍-泛型和包装类数据结构的主要内容,如果未能解决你的问题,请参考以下文章

盘点一下面试官最爱问的泛型和包装类,建议反复观看,真的写的非常详细

Java 基础语法详解 Java 中的泛型

Java 基础语法详解 Java 中的泛型

泛型和从差异类调用重载方法 - 优先级问题[重复]

初识Java集合及包装类和泛型的基本使用

JAVA数据结构List的基本用法