import java.lang.reflect.ParameterizedType;
import java.util.Arrays;
public class Ans {
public static void main(String[] args) {
test3();
test6();
}
static void test0() {
//对于List<Inter>不能转型为List<Number>有一个理解,如果可以这么做转型后就可以add(new Float(0))这明显不合适
}
static void test3() {
//在泛型中无法得到类型参数,但是如果有一个类继承了含有确定类型参数的泛型,则可以从这个类得到父类的类型参数,因为如果这时还没有任何父类类型参数的信息,子类就不知道自己可以保存什么样的数据
class A<T> {}
class AInt extends A<Integer> {}
System.out.println(Arrays.toString(A.class.getTypeParameters())); //这里的T只是个名字,毫无意义
System.out.println(AInt.class.getGenericSuperclass().getTypeName()); //这是类型参数的类名
System.out.println(Arrays.toString(((ParameterizedType) AInt.class.getGenericSuperclass()).getActualTypeArguments())); //这是这个类的class对象
}
static void test4() {
class A<T> {
void a(A<? extends T> a,T t) {} //对于这种传参的一个优势是可以保证a在方法中无法调用a.set(anything)这种方法,即限制了a的行为,当然一个例外是a.set(null),这个可以使用,但多是情况下是无意义的
}
}
static void test5() {
//同样的super也是为了限制一些行为
//无界通配符<?>的一个特点:A<?>可以接受一切A<>或A的向上转型,而且它也可以限制很多操作
//而且使用无界通配A<?>符代替无通配符A的一个好处是可以将一些不合适的由警告变成编译时报错
}
static void test6() {
class B {}
B []b = pickTwo(new B(),new B());
}
static <K> K[] pickTwo(K k1,K k2) {
K []k = (K [])asArray(k1,k2); //这里必须要转型
K []k0 = asArray2(k1,k2);
//! return (K [])asArray(k1,k2); //这两个都是classCastException,由于这个K[]不能传递到外界
//! return asArray2(k1,k2);
return null;
}
static Object[] asArray(Object o1,Object o2) {return new Object[]{o1,o2};}
static <T> T[] asArray2(T...objs) {return objs;}
}
class A<T> {
//! public boolean equals(T obj) {return super.equals(obj); } //这样不行,因为T被擦除为Object,这样就与Object.equals有相同的参数所以这不是一个重载,而这个表示又不是重写
static void test2() {
//泛型类中的静态方法不能使用类中的泛型参数,在下面我们可以看到方法可以含有泛型类型,但是这个T已经与类型中的T无关了,最好改一下名称
}
//! static void a(T t){}
static <T> void a(T t) {} //这个T和类中的T无关,建议改成别的名字(如下)
static <K> void b(K k) {}
}