印象中java泛型多用在容器类中,所以在其他场合的应用就没怎么注意。最近在读某个项目代码时,看到Hibernate存储数据的方法被写成泛型参数,恍然大悟。这是编程中的常用技巧,可以用于精简代码数量。于是为了深入理解,做了一些小例子,记录一下。
在容器中使用泛型的常见格式,如:
List<?> 表示接受任意类型
List<? extends AClass> 表示接受AClass及其子类型
List<? super BClass> 表示接受BClass及其父类型
除了?这种全能替代符,我们往往还有这种需求——虽然我现在还不知道使用哪种类型,但我并非是任意类型都接受。等以后一旦确定下来,就需要编译器帮我把关。
看看,这才是现实的复杂性。那么编译器有没有办法理解这一点呢?有的,就是使用通配符。
capture#XXX of ?) cannot be applied
当编译器遇到一个在其类型中带有通配符的变量时,为该类型创建一个占位符来指代 T 的类型。占位符被称为这个特殊通配符的捕获(capture)。错误消息通常是不能检验实参类型与其形参类型是否兼容。
在容器中使用泛型的常见格式,如:
List<?> 表示接受任意类型
List<? extends AClass> 表示接受AClass及其子类型
List<? super BClass> 表示接受BClass及其父类型
除了?这种全能替代符,我们往往还有这种需求——虽然我现在还不知道使用哪种类型,但我并非是任意类型都接受。等以后一旦确定下来,就需要编译器帮我把关。
看看,这才是现实的复杂性。那么编译器有没有办法理解这一点呢?有的,就是使用通配符。
我们对一个类或接口声明中使用了泛型标记,就可以在变量、方法、参数中来约束它。下面是示例代码:
package com.gen.zjc;
//泛型学习
import java.util.ArrayList;
import java.util.List;
//通配符可以用任意字符,但习惯上使用单个大写字母
public class GenericClass<Ha,E> {
private static final Class<InnerA> innerA = InnerA.class;
private List<Integer> l1;
//容器使用泛型
private List<Ha> l2;
//普通变量使用泛型
private Ha varh;
public Ha getValue(){
return varh;
}
public void setValue(Ha h){
varh=h;
}
public GenericClass(){
//容器类使用前要初始化
l1=new ArrayList<Integer>();
l2=new ArrayList<Ha>();
}
//参数使用泛型“类”
public void test(Class<E> clazz){
System.out.println(clazz.getName());
}
static class InnerA{
//xxx内部静态类
}
public static void main(String[] args){
//情况1:不对GenericClass做类型限定,其内部容器也不做类型检查
//GenericClass gc=new GenericClass<String,InnerA>();
//情况2:对GenericClass做类型限定,l1的类型也定为List<Integer>,编译器做类型检查
GenericClass<String,InnerA> gc=new GenericClass<String,InnerA>();
gc.setValue("hello");
//情况1:所以List<Integer>类型的l1竟然也接受"abc"
//gc.l1.add("abc");
//情况2:List<Integer>类型的l1就只能接受Integer了
gc.l1.add(5);
gc.l2.add("Must be a String");
gc.test(innerA);
test(gc);
}
public static void test(GenericClass<String,? extends InnerA> gc){
System.out.println(gc.getValue());
System.out.println(gc.l1.get(0));
System.out.println(gc.l2.get(0));
}
}
在使用泛型中经常出现的编译器错误:capture#XXX of ?) cannot be applied
当编译器遇到一个在其类型中带有通配符的变量时,为该类型创建一个占位符来指代 T 的类型。占位符被称为这个特殊通配符的捕获(capture)。错误消息通常是不能检验实参类型与其形参类型是否兼容。