泛型的概念
维基百科:泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。
在Java中用 <E>
表示泛型
泛型的好处
- 将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
- 避免了类型强转的麻烦。
使用形式
含有泛型的类
格式:
修饰符 class 类名<泛型> {
…
}
public class GenericClass<E> {
private E name;
public GenericClass() {
}
public GenericClass(E name) {
this.name=name;
}
public E getName() {
return name;
}
public void setName(E name) {
this.name=name;
}
}
使用
public class GenericTest {
public static void main(String[] args) {
//创建一个泛型类修饰的对象
//不写泛型默认是Object类型
//创建一个GenericClass对象,泛型使用Integer类型
GenericClass<Integer> gc1=new GenericClass<>();
gc1.setName(100);
Integer name1 = gc1.getName();
System.out.println(name1);
System.out.println("=========================");
//创建一个对象,泛型使用String类型
GenericClass<String> gc2=new GenericClass<>();
gc2.setName("果然这是一个字符串类型");
String name2 = gc2.getName();
System.out.println(name2);
}
}
含有泛型的方法
格式:
修饰符 <泛型> 返回值类型 方法名(修饰列表(使用泛型)){
方法体;
}
public class GenericMethod {
public <E> void method1(E e) {
System.out.println(e);
}
public static <A> void method2(A e) {
System.out.println("这是一个静态方法");
System.out.println(e);
}
}
测试
public class GenericMethodTest {
/*
含有泛型的方法,在调用方法的时候确定泛型的数据类型
传递什么类型的参数,泛型就是什么类型
*/
public static void main(String[] args) {
GenericMethod me1=new GenericMethod();
//调用时确认是字符串型
me1.method1("abc");
//调用时确认是Integer型
me1.method1(123);
System.out.println("===================");
me1.method2("静态方法,不建议创建对象使用"); //不会自动推荐,强行输入还是可以运行
//通过类名.方法名(参数) 直接调用
GenericMethod.method2('a');
GenericMethod.method2("abc");
GenericMethod.method2(123);
}
}
含有泛型的接口
格式:
修饰符 interface 接口名<泛型> {
…
}
定义一个含有泛型的接口
public interface GenericInterface<I> {
public void method1(I i);
}
定义泛型接口实现类(使用方法一)
public class GenericInterfaceImpl implements GenericInterface<String> {
@Override
public void method1(String s) {
System.out.println(s);
}
}
说明:指定接口为String类型,则实现类方法默认为String类型
未指定则默认为 Object类型
定义泛型接口实现类(使用方法二)
public class GenericInterfaceImpl2<I> implements GenericInterface<I> {
@Override
public void method1(I i) {
System.out.println(i);
}
}
说明:创建对象的时候才确定泛型的类型
测试含有泛型接口
public class GenericInterfaceTest {
public static void main(String[] args) {
//方法一测试
method1Test();
System.out.println("====================");
//方法二测试
method2Test();
}
private static void method1Test() {
//新建一个实现类对象
GenericInterfaceImpl gc1=new GenericInterfaceImpl();
gc1.method1("ABC"+100);
}
private static void method2Test() {
//新建一个实现类对象 String类型
GenericInterfaceImpl2<String> gc2=new GenericInterfaceImpl2<>();
gc2.method1("ABC"+100);
//再创建一个对象 Integer 类型
GenericInterfaceImpl2<Integer> gc3=new GenericInterfaceImpl2<>();
gc3.method1(100+100);
}
}
结论:
- 若在含有泛型接口实现类中指定泛型的类型,则创建该类对象时只能用指定的类型。所有对象类型相同。
- 若在含有泛型接口实现类中也是用泛型,则需在创建对象时指定所用类型,对象类型可不同。
通配符
格式
<?>? 表示未知通配
使用方式:
不能创建对象使用
只能作为方法的参数使用
代码演示:
import java.util.ArrayList;
import java.util.Iterator;
public class GenericLast {
public static void main(String[] args) {
ArrayList<String> list1=new ArrayList<>();
list1.add("aaa");
list1.add("bbb");
list1.add("ccc");
ArrayList<Integer> list2=new ArrayList<>();
list2.add(100);
list2.add(200);
list2.add(300);
method(list1);
method(list2);
}
/*
定义一个方法,遍历所有类型的集合
*/
public static void method(ArrayList<?> list) {
Iterator<?> it=list.iterator();
while(it.hasNext()) {
Object ne=it.next();
System.out.println(ne);
}
}
}
说明:本文参考黑马课程,在此仅作笔记使用。