泛型复习
- 泛型的生命周期
- 泛型类
- 泛型接口
- 泛型方法
-
- 关于泛型方法的总结
- 泛型通配符
-
- 有限制的通配符
泛型的生命周期
- Java中的泛型,只在
编译阶段有效
,在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦除,并且在对象进入和离开方法的边界处添加类型检查和类型转换方法。也就是说,泛型信息不回进入到运行时阶段
。
泛型类
class A<T>
{
private T key;
public T getKey() {
return key;
}
public void setKey(T key) {
this.key = key;
}
}
泛型类使用测试:
//在new A对象的时候,指定泛型的类型为String
A<String> a1=new A<>();//这边有自动类型推导
//对象使用setKey(T key)方法中的key形参就是String类型
a1.setKey("大忽悠");
String key = a1.getKey();
A<Integer> a2=new A<>();
a2.setKey(1);
Integer key1 = a2.getKey();
//在创建对象时,不指定泛型,那么相当于指定了一个Object类型
A a3=new A();
a3.setKey("大忽悠");
Object key2 = a3.getKey();在这里插入代码片
同样的类,但是在new对象时泛型指定不同数据类型,这些对象不能互相赋值
泛型接口
public interface Dhy<T>
{
T test(T t);
}
类实现该接口,但是不写泛型,默认是Object类型,同上
public class DhyImpi implements Dhy
{
@Override
public Object test(Object o) {
return null;
}
}
类实现接口,未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需要将泛型的声明也一起加到类中
public class DhyImpi<T> implements Dhy<T>
{
@Override
public T test(T t) {
return null;
}
}
如果不声明泛型,如:
public class DhyImpi implements Dhy<T>
编译器会报错: "Unknown class"
如果实现接口时,指定了接口的泛型的具体数据类型,这个类实现接口所有方法的位置都要指定泛型替换实际的具体数据类型
public class DhyImpi implements Dhy<Integer>
{
@Override
public Integer test(Integer integer) {
return null;
}
}
泛型方法
public class Xpy<E>
{
//静态变量的类型不能是泛型
//static private E e;
private E e;
//静态方法的泛型
public static <T> void test3(T t)
{
//在静态方法中,不能使用类定义的泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
//System.out.println(e);
System.out.println(t);
}
//在修饰符后面加上泛型,那么当前方法内部就可以使用该泛型
public <T> void show(T t)
{
//在类上定义的泛型,可以在普通的方法中进行使用
System.out.println(e);
T s=t;
}
public <T> T test(T t)
{
return t;
}
//可变参数的泛型方法
public <T> void test2(T...str)
{
for (T t : str) {
System.out.println(t);
}
}
}
关于泛型方法的总结
- 泛型方法,在调用之前没有固定的数据类型
- 在调用时,传入的参数是什么类型,就会把泛型改成什么类型
- 泛型方法会在调用时确定泛型具体的数据类型
- 静态变量类型不能是泛型
- 静态方法只能使用当前静态方法定义的泛型
泛型通配符
package demo02;
import java.util.ArrayList;
import java.util.Iterator;
/*
泛型的通配符:
?代表任意的数据类型
使用方式:
不能创建对象使用
只能作为方法的参数使用
*/
public class demo02Generic {
public static void main(String[] args) {
ArrayList<Integer> list1=new ArrayList<>();
list1.add(1);
list1.add(2);
ArrayList<String> list2=new ArrayList<>();
list2.add("哈哈");
list2.add("嗯嗯");
printArray(list1);
printArray(list2);
}
/*
定义一个方法,能遍历所有类型的ArrayList集合
这时候我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符
?来接受数据类型
注意:
泛型没有继承概念
*/
public static void printArray(ArrayList<?> list){
//使用迭代器遍历集合
Iterator<?> it=list.iterator();
while(it.hasNext()){
//it.next()方法,取出的元素是Object,可以接收任意的数据类型
Object i=it.next();
System.out.println(i);
}
}
}
有限制的通配符
package demo02;
import java.util.ArrayList;
import java.util.Collection;
public class Demo03Generic {
public static void main(String[] args) {
Collection<Integer> list1=new ArrayList<Integer>();
Collection<String> list2=new ArrayList<String>();
Collection<Number> list3=new ArrayList<Number>();
Collection<Object> list4=new ArrayList<Object>();
getElement(list1);
getElement(list2);//报错
getElement(list3);
getElement(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
/*
类与类之间的继承关系
Integer extends Number extends Object
String extends Object
*/
}
//泛型的上限:此时的泛型?,必须是Number类型或者Number类型的子类
public static void getElement(Collection<? extends Number> coll) {
}
//泛型的下限:此时的泛型?,必须是Number类型或者Number的父类
public static void getElement2(Collection<? super Number> coll){}
}