泛型知识点总结

2023-12-29 16:49:44

泛型知识点总结

? 1.我们在声明完自定义泛型类以后,可以在类内部(比如:属性、方法、构造器中)使用类的泛型。

? 2.我们在创建自定义泛型类的对象时,可以指明泛型参数类型,一旦指明,内部凡是使用类的泛型参数的位置,都要具体化为指定的类的泛型类型。

? 3.如果在创建自定义泛型类的对象时,没有指名泛型参数类型,那么泛型将被擦除,泛型对应的类型均按照Object处理,但不等价于Objcet。

? 4.泛型的指定中必须使用引用数据类型。不能使用基本数据类型,此时只能使用保证类替换

? 5.除创建泛型类对象外,子类继承泛型类是、实现类实现泛型接口时,也可以确定泛型结构中的泛型参数。

?	public class Sub2 extends Order<Integer>{

?    }

? 在给泛型类提供子类时,子类也不确定泛型的类型,则可以使用泛型参数。

?

	public class Sub3<T> extends Order<T>{

?    }

? 还可以在现有的父类的泛型参数的基础上,新增泛型参数。

?	public class Sub5<T,E> extends Order<T>{

?    }

?	public class Sub4<E> extends Order<Integer>{

?    }

? 注意点

? 1.泛型类可能用多个参数,此时应将多个参数一起放在简括号内。比如<E1,E2,E3>

? 2.JDK7.0开始,泛型的简化操作:

ArrayList<Fruit> list =new ArryList<>();

? 3.如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象(本来语法就不行)

? 4.不能使用 new E[ ]。但是可以:

E[ ] elements=(E[ ])new Object [capacity];

? 参考:ArrayList源码中声明:Object [ ] elementData,而非泛型参数类型数组。

5.在类/接口上声明的泛型,在本类或本类接口中即代表某种类型,但不可以在静态方法中使用类的泛型。

? (不能在静态方法使用!!!)

6.异常类不能是带泛型的。

2.自定义泛型方法

2.1 问题:在泛型类的方法中,使用类类的泛型参数。那么此方法是泛型方法么?不一定

2.2格式

权限修饰符 返回值类型 方法名(参数列表)

2.3举例

public E method(E e){ //通常在形参列表或返回值类型的位置会出现泛型参数T

public <T> ArrayList<T> copyFromArrayList(T[] arr){
    ArrayList<T> ts = new ArrayList<T>();
    for (int i=0;i< arr.length;i++){
        ts.add(arr[i]);
    }
    return ts;
  }

2.4 说明

声明泛型方法时,一定要添加泛型参数

泛型参数在方法调用时,指明其具体需求

泛型方法可以根据需要声明为static的

泛型方法所属的类是不是一个泛型类都可以

package com.genericity;

import org.junit.Test;

import java.util.ArrayList;

/**
 * @Author Tom
 * @Date 2023/12/26 10:48
 * @Description: 测试泛型类
 */
public class GenericTest {
    @Test
    public void test1() {
        //实例化时,就可以指明类的泛型参数的类型
        Order order = new Order();
        Object obj=order.getT();

        //泛型参数在指明时,是不可以使用基本数据类型的!但是可以使用包装类替代基本数据类型。
        //Order<int> order1=new Order<>();
        //在实例话时,可以指明类的泛型参数的具体类型!一旦指明泛型的类型,则在泛型类中凡是使用泛型
        //参数的位置,都替换为指定的类型
        Order<Integer> order2=new Order<>();
        order2.setT(12);
        Integer t = order2.getT();
        System.out.println(t);
    }


    @Test
    public void test2() {
        //体现继承型的多态性
        Object object1=null;
        String str1=null;
        object1=str1;

        Object[] object2=null;
        String[] str2=null;
        object2 = str2;
    }
    @Test
    public void test3(){
        ArrayList<Object> list1 = new ArrayList<Object>();
        ArrayList<String> list2 = new ArrayList<String>();
        //list1=list2;
        // list1=list2; //不可以
        /**
         * 反证法:
         * 假设list1=list2是可以的
         * list2.add("AA")
         * list1.add(123);
         * String str-list2.get(1);//相当于取的123赋值给str。错误的
         * 总结不行
         */

    }
}

1.SuperA是类A的父类,则G与G的关系:

? 并列的两个类,没有任何子父类关系,不能以多态互相赋值

@Test
public void test4(){
    List <String> list1=null;
    ArrayList<String>list2=new ArrayList<>();
    list1=list2;
}

2.类SuperA是类A的父类或接口,SuperA 与A 的关系:SuperA 与 A 有继承或实现的关系。

? 即A 的实例可以赋值给SuperA 类型的引用(或变量)

比如:List 与 ArrayList

public static <E> List<E> exchangeArray(E []arr){
    ArrayList<E> es = new ArrayList<E>();
    for (int i=0;i< arr.length;i++){
        es.add(arr[i]);
    }
    return  es;
}

通配符
2.使用说明

举例:ArrayList<?>

G<?>可以看做是G类型的夫类,即可以将G的对象赋值给G<?>类型的引用(或变量)

3.读写数据的特点(以集合ArrayList<?>为例说明)

读取数据:允许的,读取的值的类型为Object类型

写入数据:不允许的。特例:写入null值

4.有限条件的通配符

List<? extends A> :可以将List或List赋值给List<? extends A>。其中B类是A类的子类

List<? Super A> :可以将List或List赋值给List<? Super A>。其中B类是A类的父类

例子

class Father{} 父类略

class Son extends Father{} 子类略

@Test
public void test5(){
        List<? extends Father> list=null;
        List <Object> list1=null;
        List <Father> list2=null;
        List <Son> list3=null;
        list=list1; //false
        list=list2; //true
        list=list3; //true
}
@Test // 相当于>=
public void test5(){
        List<? extends Father> list=null;
        List <Father> list1=null;
        list1.add(new Father());
        list=list1;
        //读取数据可以!!而且数据类明确
         Father father = list.get(0);
          System.out.println(father);
        //写入数据不行!!
        list.add(new Father());
}
@Test // 相当于>
public void test6(){
    List<? super Father> list=null;
    List <Father> list1=null;
    list1.add(new Father());
    list=list1;
    //读取数据可以 但是类型不明确
    Object obj = list.get(0);
    System.out.println(list.get(0));

    //写入数据  可以将 子类或者父类写入进来
    list.add(null);
    list.add(new Father());
    list.add(new Son());
}

文章来源:https://blog.csdn.net/Sakura_syh/article/details/135219114
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。