Java 泛型

2021-07-30  本文已影响0人  bowen_wu

概述

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); // 编译器不报错,运行时因为擦除,也不会报错
}

泛型的绑定

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

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
上一篇下一篇

猜你喜欢

热点阅读