美文网首页
Java 泛型

Java 泛型

作者: BitterOutsider | 来源:发表于2020-12-07 10:48 被阅读0次

为什么需要泛型

假设我们在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<>();

泛型的擦除

  • 引入泛型后,为了保证向后兼容性,有两条路可以选择:1.擦除(Java的选择) 2.搞一套全新的API(C#的选择)。为了验证Java是类型擦除的,我们写了如下的代码:
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
  // .......
}     
  • 我们知道StringObject的子类, String[]Object[]的子类。但List<String>并不是List<Object>的⼦类型。

泛型的绑定

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

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;
        }
    }
}

相关文章

  • Java泛型教程

    Java泛型教程导航 Java 泛型概述 Java泛型环境设置 Java泛型通用类 Java泛型类型参数命名约定 ...

  • 第二十八课:泛型

    泛型出现之前 泛型出现之后 Java深度历险(五)——Java泛型

  • Kotlin 泛型

    说起 kotlin 的泛型,就离不开 java 的泛型,首先来看下 java 的泛型,当然比较熟悉 java 泛型...

  • java泛型中类型擦除的一些思考

    java泛型 java泛型介绍 java泛型的参数只可以代表类,不能代表个别对象。由于java泛型的类型参数之实际...

  • Java泛型

    参考:Java知识点总结(Java泛型) 自定义泛型类 自定义泛型接口 非泛型类中定义泛型方法 继承泛型类 通配符...

  • Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型

    Java泛型—Java语法糖,只在编译有作用,编译后擦出泛型 在代码进入和离开的边界处,会处理泛型 Java泛型作...

  • JAVA 核心笔记 || [xxx] 泛型

    泛型 JAVA 的参数化类型 称为 泛型 泛型类的设计 Learn12.java 运行

  • 简单回顾Java泛型之-入门介绍

    什么时候开始有了Java泛型?什么是Java泛型?为什么要引入Java泛型?什么时候用到了泛型?可不可以给泛型下一...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • JAVA-泛型

    JAVA-泛型 sschrodinger 2018/11/15 简介 泛型是Java SE 1.5的新特性,泛型的...

网友评论

      本文标题:Java 泛型

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