Java 泛型

2020-12-07  本文已影响0人  BitterOutsider

为什么需要泛型

假设我们在2000年,那时候是没有泛型的,如何实现类型安全呢?答案是没办法,我们可以在一个 List中随心所欲的添加不同类型的对象。如果一定要实现一个只能放String类型的List怎么办?只能用如下的代码。如果还需要一个只能Integer类型的呢?我们需要复制好多次,才能实现全部的需求。

class StringListDecorator {
    List list = new ArrayList();

    void add(String s) {
        list.add(s);
    }

    int size() {
        return list.size();
    }

    String get(int i) {
        return (String) list.get(i);
    }
}

有了泛型后,一切都简单了。泛型的好处:1.安全 2.方便。

List<String> list = new ArrayList<>();

泛型的擦除

public class Main {
    public static void main(String[] args) {
        String[] strings = new String[0];
        new ArrayList();
    }
}

使用ASMPlugin插件去看字节码,我们可以清楚的看到,L0:数组确实是有类型String的。而L1:ArrayList的类型却被擦除了。那为什么我们往带String泛型的List中插入Integer会报错呢?这只是编译器报错,Java的泛型是假泛型,是编译期的泛型,泛型信息在运⾏期完全不保留。所以说我们只要绕过编译器的检查,一切泛型都没有了,运行时是不会去检查的。

 public class com/github/lazyben/Main {
  // .......
  public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 8 L0
    ICONST_0
    ANEWARRAY java/lang/String
    ASTORE 1
   L1
    LINENUMBER 9 L1
    NEW java/util/ArrayList
    DUP
    INVOKESPECIAL java/util/ArrayList.<init> ()V
    ASTORE 2
  // .......
}     

泛型的绑定

看一个简单的例子,我们可以做一个泛型的绑定以简化代码。

public class Main {
    public int max(int a, int b) {
        return a > b ? a : b;
    }

    public double max(double a, double b) {
        return a > b ? a : b;
    }

    public long max(long a, long b) {
        return a > b ? a : b;
    }
}

声明<T extends Comparable>表示T一定继承了Comparable接口,JVM会根据你传进来的参数做泛型的绑定。extends要求泛型是某种类型及其⼦类型

public <T extends Comparable<T>> T max(T a, T b) {
    return a.compareTo(b) > 0 ? a : b;
}

再来看一个关于super的例子,以Collections.sort为例:

public static <T> void sort(List<T> list, Comparator<? super T> c) {
    list.sort(c);
}

sort的第二个参数接受一个Comparator,他的泛型必须是T及其父类,由此Comparator<Cat>Comparator<Animal>都是可以的。 super要求泛型是某种类型及其⽗类型

public class Main {
    public static void main(String[] args) {
        final ArrayList<Cat> cats = new ArrayList<>();
        Collections.sort(cats, new CatComparator());
        Collections.sort(cats, new AnimalComparator());
    }

    static class CatComparator implements Comparator<Cat> {
        @Override
        public int compare(Cat o1, Cat o2) {
            return 0;
        }
    }

    static class AnimalComparator implements Comparator<Animal> {
        @Override
        public int compare(Animal o1, Animal o2) {
            return 0;
        }
    }
}
上一篇 下一篇

猜你喜欢

热点阅读