一:泛型
泛型类:class FanxingTest<T>{ }
泛型方法:public <T> T fanxingMethod(T...a){ // 泛型方法
return a[a.length/2];
}
示例:
public class GenericMethod3 {
static class Fruit{
@Override
public String toString() {
return "fruit";
}
}
static class Apple extends Fruit{
@Override
public String toString() {
return "apple";
}
}
static class Person{
@Override
public String toString() {
return "Person";
}
}
static class GenerateTest<T>{ // 泛型类
//普通方法
public void show_1(T t){
System.out.println(t.toString());
}
//在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。
// 可以类型与T相同,也可以不同。
//由于泛型方法在声明的时候会声明泛型<E>,因此即使在泛型类中并未声明泛型,
// 编译器也能够正确识别泛型方法中识别的泛型。
public <E> void show_3(E t){ // 泛型方法
System.out.println(t.toString());
}
//在泛型类中声明了一个泛型方法,使用泛型T,
// 注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。
public <T> void show_2(T t){ // 泛型方法
System.out.println(t.toString());
}
}
public static void main(String[] args) {
Apple apple = new Apple();
Person person = new Person();
GenerateTest<Fruit> generateTest = new GenerateTest<>();
generateTest.show_1(apple);
//generateTest.show_1(person); // 编译报错
generateTest.show_2(apple);
generateTest.show_2(person);
generateTest.show_3(apple);
generateTest.show_3(person);
}
}
二 :通配符
限定上界:? extends XXX (规定了:只能传入的参数是XXX,或者XXX的子类,XXX的父类/或者以上的类不能传,上界)
限定下界:? super XXX (规定了:只能传入的参数是XXX, 或者XXX 的父类,XXX 的子类/或者以下的类不能传,下界)
示例:(Food-Fruit-Orange/Apple(Apple-HongFuShi))
public class WildChar{
public static void print(GenericType<Fruit> p){ // print 只接受 GenericType<Fruit>参数,即是GenericType类型而且泛型是Fruit
System.out.println(p.getData().getColor());
}
public static void use(){
GenericType<Fruit> a = new GenericType<>();
print(a); // a 对象是 GenericType类型,而且泛型是Fruit
GenericType<Orange> b = new GenericType<>();
//print(b); // 报错,因为 b的类型,虽然是GenericType,但是泛型是Orange, 不能调用print()方法
}
public static void print2(GenericType<? extends Fruit> p){ // 通配符? ,这里只能传入Fruit,及其子类,上界是Fruit, Fruit 上面的类Food是会报错的
System.out.println(p.getData().getColor());
}
public static void use2(){
GenericType<Fruit> a = new GenericType<>();
print2(a);
GenericType<Orange> b = new GenericType<>();
print2(b);
//print2(new GenericType<Food>()); // 报错,上界是Fruit,但是传入了Fruit 的父类Food 是不可以的
GenericType<? extends Fruit> c = new GenericType<>();
Apple apple = new Apple();
Fruit fruit = new Fruit();
//c.setData(apple);
//c.setData(fruit);
Fruit x = c.getData(); // 因为c 获取到的一定是 Fruit 类或者Fruit的子类,所以可以去get
}
public static void printSuper(GenericType<? super Apple> p){
System.out.println(p.getData());
}
public static void useSuper(){
GenericType<Fruit> fruitGenericType = new GenericType<>();
GenericType<Apple> appleGenericType = new GenericType<>();
GenericType<HongFuShi> hongFuShiGenericType = new GenericType<>();
GenericType<Orange> orangeGenericType = new GenericType<>();
printSuper(fruitGenericType);
printSuper(appleGenericType);
// printSuper(hongFuShiGenericType); // 报错,下界是Apple, 只能传Aplle,或者Apple 的父类,printSuper方法的参数规定了下界
// printSuper(orangeGenericType);
//表示GenericType的类型参数的下界是Apple
GenericType<? super Apple> x = new GenericType<>();
x.setData(new Apple());
x.setData(new HongFuShi());
//x.setData(new Fruit());
Object data = x.getData();
}
}
三:泛型擦除
示例:
public class Restrict<T> {
private T data;
//不能实例化类型变量
// public Restrict() {
// this.data = new T();
// }
//静态域或者方法里不能引用类型变量
//private static T instance;
//静态方法 本身是泛型方法就行
//private static <T> T getInstance(){}
public static void main(String[] args) {
//Restrict<double>
Restrict<Double> restrict = new Restrict<>();
Restrict<String> restrictString= new Restrict<>();
System.out.println(restrict.getClass()==restrictString.getClass()); // true,因为两者打印出来都是Restrict
System.out.println(restrict.getClass().getName()); // cn.enjoyedu.generic.Restrict
System.out.println(restrictString.getClass().getName()); // cn.enjoyedu.generic.Restrict
Restrict<Double>[] restrictArray; // 带泛型的数组,声明可以,初始化不行
//Restrict<Double>[] restricts = new Restrict<Double>[10]; // 带泛型的数组,声明可以,初始化不行
//ArrayList<String>[] list1 = new ArrayList<String>[10]; // 带泛型的数组,声明可以,初始化不行
//ArrayList<String>[] list2 = new ArrayList[10]; // 带泛型的数组,声明可以,初始化不行
}
}