美文网首页
Java 泛型

Java 泛型

作者: bowen_wu | 来源:发表于2021-07-30 10:56 被阅读0次

    概述

    since 1.5

    泛型优点

    1. 类型安全
    2. 类型确定,方便使用该类型的方法,如果没有确定需要强制转换

    泛型从无到有,是否要支持无泛型的原始类型

    1. 擦除 => Java 的选择
    2. 搞一套全新的 API => C# 的选择

    擦除 erasure

    在运行时泛型相关信息被抹除掉了 => 字节码中没有泛型相关信息

    这两个 ` foo ` 方法在泛型擦除后有相同的参数

    Java 的泛型是假泛型,是编译期的泛型 => 泛型信息在运行期完全不保留 => 在运行时没有安全保障 => Java 的泛型只有编译器检查
    可以通过利用泛型擦除来绕过编译器检查

    public static void testArraySafety(Object[] array) {
      array[0] = 1;
    }
    
    public static void testListSafety(List<Object> list) {
        list.add(1);
    }
    
    public static void main(String[] args) {
        String[] array = new String[2];
        testArraySafety(array); // 编译器不报错,运行时报错
    
        List<String> list = new ArrayList<>();
        testListSafety(list); // 编译报错
        testListSafety((ArrayList) list); // 编译器不报错,运行时因为擦除,也不会报错
    }
    

    泛型的绑定

    调用方法时会自动进行泛型的绑定

    • ? extends T => 要求泛型是某种类型及其子类型
    • ? super T => 要求泛型是某种类型及其父类型
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }
    
    // T => Cat
    public static void main(String[] args) {
        sort(new ArrayList<Cat>(), new CatComparator());
        sort(new ArrayList<Cat>(), new AnimalComparator());
    }
    

    按照参数绑定

    //  此时的 Comparable 是一个裸的类型
    public static <T extends Comparable> T max(T a, T b) {
        return a.compareTo(b) >= 0 ? a : b;
    }
    
    public static <T extends Comparable<T>> T max1(T a, T b) {
        return a.compareTo(b) >= 0 ? a : b;
    }
    
    public static void main(String[] args) {
        max("aaa", 1); // max(Comparable, Comparable) => 泛型绑定为 Comparable => 运行时报错
        max1("aaa", 1); // IDE 报错
    }
    
    public static <A extends Comparable, B extends Comparable> A max(A a, B b) {
        return a;
    }
    
    max("aaa", 1) error

    按照返回值自动绑定

    public static <T> T cast(Object obj) {
        return (T) obj;
    }
    public static void main(String[] args) {
        String string = cast("");
        Integer i = cast(123);
    }
    

    知识点

    1. JVM 的只能运行字节码,和 Java 代码没有任何关系
    2. 数组的类型信息是完全安全的
    3. Java 重要的约定
      1. equals 约定 => 对于非空引用值
        • It is reflexive => x.equals(x) == true
        • It is symmetric => if x.equals(y) == true 那么 y.equals(x) == true
        • It is transitive => x.equals(y) == true && y.equals(z) == true 那么 x.equals(z) == true
        • It is consistent => 如果没有更改 equals 方法,那么 x.equals(y) 多次调用结果保持一致
        • x.equals(null) == false
      2. hashCode 约定 // TODO
      3. interface Comparable => compareTo

    相关文章

      网友评论

          本文标题:Java 泛型

          本文链接:https://www.haomeiwen.com/subject/cnefvltx.html