前言
为什么要使用泛型?
泛型可以对添加到集合中的元素进行限制!
- 代码示例
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("唐朝");
list.add("明朝");
list.add("清朝");
//Integer类型不能转换为字符串
list.add(1);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
// 如果添加泛型进行限制的话,就会有错误发生
String next = (String)iterator.next();
int length = next.length();
System.out.println(length);
}
}
1. 泛型
1.1 泛型概述
- 泛型的介绍
泛型是JDK5中引入的特性,他提供了编译时类型安全监测机制。 - 泛型的好处
把运行期间的问题提前到了编译期间
避免了强制类型转换 - 泛型的定义格式
<类型>: 指定一种类型的格式,尖括号里边可以任意书写,一般用一个字母表示。例如:
<类型1,类型2…>: 指定多种类型的格式,多种类型之间用逗号隔开。例如:<E,T><K,V>
1.2 泛型类
- 定义格式
修饰符 class 类名<类型> { }
- 代码示例
public class Person<E> {
private E element;
public E getElement() {
return element;
}
public void setElement(E element) {
this.element = element;
}
}
如果一个类的后面有,表示这个类是一个泛型类。
创建泛型类的对象时,必须要给这个泛型确定的数据类型。
1.3 泛型方法
- Java中的泛型方法
方法名 | 介绍 |
---|---|
Object[] toArray() | 按照适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。 |
T[] toArray(T[] a) | 按适当的顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型 |
- 代码演示
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("四大发明");
list.add("造纸术");
list.add("印刷术");
list.add("火药");
list.add("指南针");
//1.获取迭代器对象
Object[] objects = list.toArray();
System.out.println(Arrays.toString(objects));
//2.传入一个字符串类型的数组,toArray方法会把元素放到这个数组当中,并返回一个字符串类型的数组
String[] strings = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(strings));
}
- 自己定义的泛型方法
格式:修饰符<类型> 返回值类型 方法名(类型 变量名) { } - 代码示例
// 定义一个方法,里边传入一个list集合并往list集合中添加四个元素
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
addElement(list,"造纸术","印刷术","火药","指南针");
System.out.println(list);
}
public static <T> void addElement(ArrayList<T> list, T t1, T t2, T t3, T t4) {
list.add(t1);
list.add(t2);
list.add(t3);
list.add(t4);
}
1.4 泛型接口
- 格式
修饰符 interface 接口名<类型> {}
- 使用方式
① 实现类也不给泛型
public class GenericityInterface {
public static void main(String[] args) {
GenericityImpl<String> genericity = new GenericityImpl<>();
genericity.method("泛型接口");
}
}
interface Genericity<E> {
public abstract void method(E e);
}
//实现类也不给泛型
class GenericityImpl<E> implements Genericity<E> {
@Override
public void method(E e) {
System.out.println(e);
}
}
②实现类确定具体的数据类型
public class GenericityInterface {
public static void main(String[] args) {
Genericity2 genericity2 = new Genericity2();
genericity2.method(666);
}
}
interface Genericity<E> {
public abstract void method(E e);
}
// 实现类确定具体的数据类型
class Genericity2 implements Genericity<Integer> {
@Override
public void method(Integer integer) {
System.out.println(integer);
}
}
1.5 类型通配符
- 类型通配符: <?> ArrayList<?>: 表示元素类型未知的ArrayList,他的元素可以匹配任何的类型,但是并不能把元素添加到ArrayList中了,获取出来的也是父类的类型
- 类型通配符上限: <? extends 类型>
ArrayList <? extends Number>: 他表示的类型是Number或者其子类型 - 类型通配符下限: <? super 类型>
ArrayList <? super Number>: 他表示的类型是Number或者其父类型 - 代码示例
public static void main(String[] args) {
/**
* java.lang.Object
* 继承者 java.lang.Number
* 继承者 java.lang.Integer
*/
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<Number> list2 = new ArrayList<>();
ArrayList<Object> list3 = new ArrayList<>();
printList(list1);
printList(list2);
method1(list1);
method1(list2);
// method1(list3);// 报错
// method2(list1);
method2(list2);
method2(list3);
}
// 表示传递进来的集合类型是Number类型以及Number的子类类型
private static void method1(ArrayList<? extends Number> list) {
System.out.println(list);
}
// 表示传递进来的集合类型是Number类型以及Number的父类类型
private static void method2(ArrayList<? super Number> list) {
System.out.println(list);
}
private static void printList(ArrayList<?> list) {
System.out.println(list);
}
- 图解(便于理解记忆)
最后,如果本文帮助到你了的话,请帮我点个赞吧!