通配符的表示方法有<? extends T>,<? super T>,<?>.
<? extends T>表示可以引用T及T的子类
<? super T>表示可以引用T及T的父类
<?>表示无限定引用。
<? extends T>看起来与声明泛型类或函数里的类型限定<T extends A>类似,但两者有很大区别
先直观的看一下“T”,一个在extends前边,一个在extends后边。
类型限定是在声明类或函数时如:
public <T extends A>T func(T){};
通配符是在作为变量引用时使用如:
<? extends T> aObj = new Obj();
下面结合代码说明:
import java.lang.reflect.*;
class TestClass1<T>{
TestClass1(T t){
this.aT=t;
}
public T DispAndRet(){
Class<?> aDemo=null;
aDemo=aT.getClass();
Method aMethod=null;
try
{
aMethod=aDemo.getMethod("DispAndRet");
}
catch(Exception e)
{
System.out.println(aT.getClass()+": "+aT.toString());
return aT;
}
try
{
aMethod.invoke(aT);
}
catch (Exception e)
{
System.out.println("invoke error");
}
return aT;
}
private T aT;
}
class TestClass2<T> extends TestClass1<T>{
TestClass2(T t){
super(t);
}
}
class TestClass3<T> extends TestClass1<T>{
TestClass3(T t){
super(t);
}
}
public class Test2{
public static void main(String[] args){
TestClass1<String> aTest=new TestClass1<String>("this is test");
aTest.DispAndRet();
TestClass1<TestClass2> bTest=new TestClass1<TestClass2>(new TestClass2<String>("bTest ref TestClass2"));
bTest.DispAndRet();
//bTest=new TestClass1<TestClass3>(new TestClass3<String>("bTest ref TestClass3"));
//bTest.DispAndRet();
TestClass1<? extends TestClass1> cTest=new TestClass1<TestClass3>(new TestClass3<String>("cTest ref TestClass2"));
cTest.DispAndRet();
cTest=new TestClass1<TestClass2>(new TestClass2<String>("cTest ref TestClass3"));
cTest.DispAndRet();
cTest=new TestClass1<TestClass1>(new TestClass1<String>("cTest ref TestClass1"));
cTest.DispAndRet();
}
}
//////////////////
输出
class java.lang.String: this is test
class java.lang.String: bTest ref TestClass2
class java.lang.String: cTest ref TestClass2
class java.lang.String: cTest ref TestClass3
class java.lang.String: cTest ref TestClass1
///////////////////////////////////////////////
首先声明了了一个泛型类TestClass1,然后继承了两个子类TestClass2,TestClass3
main函数里先用TestClass1<String> aTest定义了一个变量引用String 类型。
用TestClass1<TestClass2> bTest引用了一个TestClass2类型,红色代码部分代码想把bTest引用TestClass3,结果编译出错
提示如下:
”required: TestClass1<TestClass2>
found: TestClass1<TestClass3>“
这是因为bTest是用TestClass1<TestClass2>定义的,只能引用TestClass2。引用TestClass3会编译出错。
接下来TestClass1<? extends TestClass1> cTest 采用通配符定义了cTest,表示 cTest可以引用TestClass1及其子类。
TestClass2和TestClass3都是其子类,下一句cTest=new TestClass1<TestClass2>(new TestClass2<String>("cTest ref TestClass3"));
把cTest引用TestClass3时就不会编译出错了。