List<? extends Data>
,而里面的 ? 称为通配符类型WildcardType@AnTest("list")List<String>list
泛型: 把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型
public class MainTest<T> {
private T param;
}
public static void main(String[] args){
MainTest<String> data = new MainTest<String>(){};
ParameterizedType genType1 = (ParameterizedType)data.getClass().getGenericSuperclass();
}
public class MainTest{
public static void main(String[] args){
printData("siting");
}
static <T> T printData(T t){
System.out.println(t);
return t;
}
}
public class MainTest {
public static void main(String[] args){
List<String> strArr = new ArrayList<>();
List<Integer> intArr = new ArrayList<>();
Type strClazz = strArr.getClass();
Type intClazz = intArr.getClass();
}
}
public class MainTest<T> {
T param;
public static void main(String[] args){
MainTest<String> test = new MainTest<>();
test.setParam("siting");
}
public T getParam() { return param; }
public void setParam(T param) { this.param = param; }
}
public class com/MainTest {
...省略
public static main([Ljava/lang/String;)V
L0
LINENUMBER 7 L0
NEW com/MainTest
DUP
INVOKESPECIAL com/MainTest.<init> ()V
ASTORE 1
L1
LINENUMBER 8 L1
ALOAD 1
LDC "siting" // 调用类型擦除后的setParam(Object)
INVOKEVIRTUAL com/MainTest.setParam (Ljava/lang/Object;)V
L2
...省略//getParam 的返回值是Object
public getParam()Ljava/lang/Object;
L0
LINENUMBER 10 L0
ALOAD 0
GETFIELD com/MainTest.param : Ljava/lang/Object;
ARETURN
...省略//setParam 的入参是Object
public setParam(Ljava/lang/Object;)V
L0
LINENUMBER 11 L0
ALOAD 0
ALOAD 1
PUTFIELD com/MainTest.param : Ljava/lang/Object;
RETURN
...
}
public class MainTest<T> {
T param;
static public class SubTest1 extends MainTest<String>{}
static public class SubTest2<R> extends MainTest<R>{}
//SubTest3继承的时原生类型
static public class SubTest3 extends MainTest{}
}
public class MainTest<T> {
List<T> param;
public static void main(String[] args) throws Exception{
Class clazz = MainTest.class;
TypeVariable[] typeVariable = clazz.getTypeParameters();
// 1
Field field = clazz.getDeclaredField("param");
ParameterizedType arrayType = (ParameterizedType)field.getGenericType();
// interface List<E> 的泛型类型E被T,具体化,因此其被识别为 TypeVariable
TypeVariable variable1 = (TypeVariable)arrayType.getActualTypeArguments()[0];
// 2
ParameterizedType type = (ParameterizedType)SubTest.class.getGenericSuperclass();
TypeVariable variable2 = (TypeVariable)type.getActualTypeArguments()[0];
}
static class SubTest<R> extends MainTest<R>{}
}
public interface ParameterizedType extends Type {
//获取实际参数,List<String>里的String; 如果是List<T>则是TypeVariable类型
Type[] getActualTypeArguments();
// 获取原始类型List<String> -> List<E>
Type getRawType();
Type getOwnerType();
}
Class clazz = List<String>.class
编译时不通过的;还有就是直接通过泛型类new创建的对象,其Class并非ParameterizedType类型,而是泛型本身的class,示例如下public class MainTest<T> {
public static void main(String[] args){
MainTest<String> str = new MainTest<String>();
Class variable = str.getClass();
Type genType1 = variable.getGenericSuperclass();
}
}
// 1 子类继承泛型时,指定具体参数(可以是String等已知类型,也可以是子类的泛型参数)
// 2 获取在类内部定义的泛型属性,需指定具体泛型参数
// 3 局部代码,可以通过泛型的匿名内部子类(需指定具体泛型参数)获取ParameterizedType类型
public class MainTest<T> {
List<T> list;
public static void main(String[] args) throws NoSuchFieldException {
SubTest<String> str = new SubTest<>();
// 方式一
Class variable = str.getClass();
// 父类是(521)ParameterizedType类型
ParameterizedType genType = (ParameterizedType)variable.getGenericSuperclass();
// (521)ParameterizedType类型的原生类型是(479)class com.MainTest
Type clazz = genType.getRawType();
//MainTest.class 的原生类型是 (479)class com.MainTest
Class rawClazz = MainTest.class;
//方式二,泛型属性
Field field = rawClazz.getDeclaredField("list");
//属性list 类型是(546)ParameterizedType类型List<T>
ParameterizedType fieldType = (ParameterizedType)field.getGenericType();
// 方式三
MainTest<String> sub3 = new MainTest<String>(){};
// clazz3是匿名子类
Class clazz3 = sub3.getClass();
//父类是(555)ParameterizedType类型
ParameterizedType genType3 = (ParameterizedType) clazz3.getGenericSuperclass();
// (555)ParameterizedType类型的原生类型是(479)class com.MainTest
Type type3 = genType3.getRawType();
}
public static class SubTest<R> extends MainTest<R>{ }
}
public static void print(List list){}
----->>>
public static void print(List<?> list){}
List<? extends Number的子类>
,表明List里的元素都是Number的子类 public static void print(List<? extends Number> list) {
Number n = new Double("1.0");
list.add(n);
Number tmp = list.get(0);
}
class Parent{ }
class Child extends Parent{ }
public class MainTest<T> {
T param;
public static void main(String[] args){
MainTest<? super Child> parent_m = new MainTest<>();
parent_m.setParam(new Child());
Object parent = parent_m.getParam();
}
public T getParam() { return param; }
public void setParam(T param) { this.param = param; }
}
public interface GenericArrayType extends Type {
//获得这个数组元素类型,即获得:A<T>(A<T>[])或 T(T[])
Type getGenericComponentType();
}
public class MainTest<T> {
T[] param;
public static void main(String[] args) throws Exception{
Class clazz = MainTest.class;
Field field = clazz.getDeclaredField("param");
GenericArrayType arrayType = (GenericArrayType)field.getGenericType();
TypeVariable variable = (TypeVariable) arrayType.getGenericComponentType();
}
}