JAVA 基础知识点复习(十五)泛型

定义

在编译时期就对元素的类型进行检查,一旦发现不匹配就编译失败。在编译时泛型就被擦除了,所以无法在运行时得知其类型参数的类型。通过泛型可以定义类型安全的数据结构(类型安全),而无须使用实际的数据类型(可扩展),这能够显著提高性能并得到更高质量的代码(高性能),因为可以重用数据处理算法,而无须复制类型特定的代码(可重用)。

泛型可以定义在类,接口,方法上

  • 定义时尖括号里的每个元素都代指一种未知类型
  • 尖括号的位置非常讲究,必须在类名之后或者方法返回值之前
  • 泛型在定义处只具备Object方法的能力
  • 基本数据类型不能作为泛型参数
// 泛型接口
public interface Genericity<T> {
    T test();
}

public class Son implements Genericity<Integer> {
    @Override
    public Integer test() {
        return null;
    }
}

// 泛型类 在编译时是无法知道K和V具体是什么类型,只有在运行时才会真正根据类型来构造和分配内存。
@Data
public class Container<K, V> {

    private K key;

    private V value;

    public Container(K key, V value) {
        this.key = key;
        this.value = value;
    }

    // 这里不能用static修饰 静态方法无法访问类上定义的泛型。
    public K test(V v){
        return null;
    }
	// String不等于java.lang.String,只是一个自定义的泛型类型
    public static <String> String test2(String str){
        return str;
    }


    public static void main(String[] args) {
        // 这里如果传入的是Integer类型,编译不会报错,运行会报ClassCastException
        Container<String, String> container = new Container(1, 2);
        System.out.println(container.getKey());
        System.out.println(container.getValue());
    }
}

泛型的限定

<? extends E> 泛型上限 接收E或者E的子类,一般在存储元素时使用上限,取值时用E来接收,不会存在类型安全问题

public static void printCollection(List<? extends Number> list){
        Number number = list.get(0);
    }

<? super E> 泛型下限 接收E或者E的父类,从集合取值时可以用E或者E的父类接收

public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }

泛型擦除

List<String> list = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
System.out.println(list.getClass() == list2.getClass()); // true

泛型擦除带来的问题

  • 不能使用泛型来重载方法
  • 2.不能catch同一个异常的不同泛型实例
  • 3.不同泛型类的静态变量是共享的
  • 4.泛型间不存在继承关系,不能使用List 来接收List类型的参数
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章