泛型

xiaoxiao2021-02-28  13

使用泛型的优点:

使用Java的泛型可以在编译时检测出错误。省心,取出元素时不用类型 List<String> list=new ArrayList<>(); //list.add(1);编译时类型检查出错误 list.add("so easy"); list.get(0);//取出时不再需要类型转换

使用泛型的一些限制:

不能使用 new E()以及new E[]; 泛型存在于编译时,一旦编译器认为泛型类型是安全的,就会将它转换为原始类型(Object)在静态上下文中不允许类的参数是泛型类型 例如: public static void m(E o1){ } 以及 private static T test 都是错误的;<font color=red>因为所有的泛型实例在运行时都用同一个运行时类,所以泛型的静态变量和方法是被它的所有实例所共享的,所以在静态方法、数据域或者初始化语句中为类引用泛型类型参数是非法的。</font> 为什么说“所有的泛型实例在运行时都用同一个运行时类”,如下代码证明: 【编译时ArrayList<String>,ArrayList<Integer>是两种不同的类型,但在运行时只有一个ArrayList加载到JVM中】 public static void main(String[] args) { ArrayList<String> list1=new ArrayList<>(); ArrayList<Integer> list2=new ArrayList<>(); System.out.println(list1 instanceof ArrayList); System.out.println(list2 instanceof ArrayList); }

3.在声明时指定类型,但不能是基本类型

泛型方法:

非泛型类中定义泛型方法 在返回类型前面加入泛型,可以使用extends让泛型局限于某些类型下,从而使泛型具有该类型的特性 public class Method3 { public static <T> void test(T t){ System.out.println(t); } //可以使用extends让泛型局限于某些类型下 public static <T extends List> void test1(T t){ t.add("I love you"); System.out.println(t.get(0)); } public static void main(String[] args) { test("I love you"); test(1024); ArrayList list=new ArrayList(); test1(list); } }

泛型的继承:

泛型的继承 * 1.保留父类的泛型,泛型子类 * 2.不保留父类泛型,子类按需实现即可,可以是泛型类也可以是非泛型类 * 3.子类也可以扩展自己的泛型也可以 * 4.子类重写的方法的泛型类型取决于父类中该方法的泛型类型 * 5.子类中使用父类的属性随父类而定 * 6.子类新增方法或属性的类型由子类自己决定

public abstract class Father4<T1, T2>{ T1 age; public abstract void test(T2 name); } /* * 保留-->泛型子类 */ //1)全部保留 class c1<T1, T2> extends Father4<T1, T2>{ @Override public void test(T2 name) { //this.age-->T1 } } //2)部分保留 class c2<T2> extends Father4<Integer, T2>{ @Override public void test(T2 name) { //this.age-->Integer } } /* * 不保留--》按需实现 */ //1)指定具体类型 class c3 extends Father4<Integer, String>{ @Override public void test(String name) { //this.age-->Integer } } //2)没有类型,擦除泛型,擦出后相当于Object class c4 extends Father4{ @Override public void test(Object name) { //this.age-->Object } } class c5<T1, T2, A, B> extends Father4<T1, T2>{ @Override public void test(T2 name) { //this.age-->T1 } }

泛型接口与泛型类同理

“?“ 通配符:类型不确定,用于声明变量|形参 1、变量的类型(局部变量&成员变量)

List<? extends Fruit> list1 =new ArrayList<Fruit>();

2、方法形参的类型

public stati cvoid test(List<?> list)

extends: 泛型的上限

public class Fruit8 { } class Apple extends Fruit8{} class Pear extends Fruit8{} class FujiApple extends Apple{}

===================================

public class ExtendsTest8 { public static void main(String[] args) { Test<Fruit8> t1=new Test<Fruit8>(); Test<Apple> t2=new Test<Apple>(); Test<Pear> t3=new Test<Pear>(); Test<FujiApple> t4=new Test<FujiApple>(); //调用方法 List<? extends Fruit8> list1=new ArrayList<Fruit8>(); test(list1); List<Apple> list2=new ArrayList<Apple>(); test(list2); //? extends Apple List<? extends Apple> list4=new ArrayList<FujiApple>(); test(list4); //?-->为什么错误 List<?> list5=new ArrayList<Apple>(); //test(list5); List<?> list6=new ArrayList<Object>(); //test(list6); //? 相当于任何类型的对象都可以,假设对象超出Fruit8,如Object, //所以 声明对象时用 ,即使创建对象时使用的泛型在Fruit8内也不行 } //? extends Fruit8 public static void test(List<? extends Fruit8> list){ //不能向list添加任何对象 //list.add(new Apple()); //list.addAll(new Pear()); list.add(null); } } class Test<T extends Fruit8>{}//extends表示泛型上限为Fruit8,T可以是所有Fruit8的子类

super: 泛型的下限

public class SuperTest { public static void test(List<? super Apple> list){ //只能添加子对象和自己 list.add(new Apple()); list.add(new FujiApple()); //list.add(new Pear()); //list.add(new Fruit8()); } public static void main(String[] args) { List<Apple> list1=new ArrayList<Apple>(); List<Fruit8> list2=new ArrayList<Fruit8>(); List<Object> list3=new ArrayList<Object>(); List<? super Apple> list4=new ArrayList<Apple>(); List<? super Fruit8> list5=new ArrayList<Fruit8>(); List<FujiApple> list6=new ArrayList<FujiApple>(); List<Pear> list7=new ArrayList<Pear>(); //规则 //apple为下限,Apple的父类以及超类均可以,子类和与Apple同属于一个父类的其他类不可以 test(list1); test(list2); test(list4); test(list5); //test(list6); //test(list7); }
转载请注明原文地址: https://www.6miu.com/read-200175.html

最新回复(0)