泛型

作者: 李军_6eaa | 来源:发表于2018-01-13 11:09 被阅读0次
为什么在泛型中,不要使用原始类型(不带类型参数的泛型)?比如要使用List<?>,不要简单的使用List
  • 使用不带类型参数的泛型,会丢掉泛型所有的安全性和富有表现力的好处
  • 之所有不带类型参数的泛型合法,是为了兼容java5之前的旧代码
  • 在class literals中必须要用raw types,比如:List.class, String[].class,int.class,而不能使用List<String>.class 和 List<?>.class。
  • 在instanceof操作中,要用raw types,比如:
if (o instanceof Set) {       // Raw type
    Set<?> s = (Set<?>) o;    // Wildcard type
    ...
}
泛型中,Set<String>,Set<Object>,Set<?>,以及Set的区别?
  • Set<String>代表set中的元素是String类型;Set<String>,Set<Object>和Set<?> 都是Set的子类型;Set<Object>代表set中的元素是Object类型;Set<?>是一个通配符类型,代表set中的元素只能是某种未知类型的Objects;而Set是raw type,它不属于泛型系统。
在泛型中,相对于Array,为什么优先使用List?
  • Array是协变的(covariant),即共同变化,比如
Sub 是 Super的子类型,Sub[] 也是 Super[]的子类型

而List是不变的(invariant),即对于两个不同的类型Type1 和 Type2,则List<Type1>既不是List<Type2>的子类型,也不是List<Type2>的超类型。

  • Array是reified(物化, 具体的),即它确保运行期类型的正确性;而List是erasure(擦除化的),即它确保编译期类型的正确性,而在运行期时,它的元素的具体类型被丢弃(erasure是为了兼容Java5之前的代码)
  • 由于上述两点,java 禁止创建泛型数组
拥抱泛型
  • Object-based 应该重构成generic types
如何使用有边界通配符以增加API的灵活性?
  • PECS stands for producer-extends, consumer-super
  • E 替换成? extends E 或者? super E
  • 不要使用有边界通配符作为return types
  • 在一个方法签名中,如果一个类型参数E只出现一次,则把替换成通配符?
为什么尽量不要把泛型(generics)和不定参数(varargs)混合使用
  • 因为varargs是建立在数组上的抽象,而数组和泛型有着不和谐的交互
解释泛型中的type token(类型标记)
public class Favorites {
    private Map<Class<?>, Object> favorites = new HashMap<>();

    public <T> void putFavorite(Class<T> type, T instance) {
        favorites.put(Objects.requireNonNull(type), type.cast(instance));
    }

    public <T> T getFavorite(Class<T> type) {
        return type.cast(favorites.get(type));
    }

    public static void main(String[] args) {
         Favorites f = new Favorites();
         f.putFavorite(String.class, "Java");
         f.putFavorite(Integer.class, 0xcafebabe);
         f.putFavorite(Class.class, Favorites.class);
         String favoriteString = f.getFavorite(String.class);
         int favoriteInteger = f.getFavorite(Integer.class);
         Class<?> favoriteClass = f.getFavorite(Class.class);
         System.out.printf("%s %x %s%n", favoriteString, favoriteInteger, favoriteClass.getName());
    }
}

相关文章

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

  • 泛型的使用

    泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法 泛型类 泛型接口 泛型通配符 泛型方法 静态方法与...

  • Java 泛型

    泛型类 例如 泛型接口 例如 泛型通配符 泛型方法 类中的泛型方法 泛型方法与可变参数 静态方法与泛型 泛型上下边...

  • 探秘 Java 中的泛型(Generic)

    本文包括:JDK5之前集合对象使用问题泛型的出现泛型应用泛型典型应用自定义泛型——泛型方法自定义泛型——泛型类泛型...

  • Web笔记-基础加强

    泛型高级应用 自定义泛型方法 自定义泛型类 泛型通配符? 泛型的上下限 泛型的定义者和泛型的使用者 泛型的定义者:...

  • 重走安卓进阶路——泛型

    ps.原来的标题 为什么我们需要泛型? 泛型类、泛型接口和泛型方法(泛型类和泛型接口的定义与泛型方法辨析); 如何...

  • Kotlin泛型的高级特性(六)

    泛型的高级特性1、泛型实化2、泛型协变3、泛型逆变 泛型实化 在Java中(JDK1.5之后),泛型功能是通过泛型...

  • Java 19-5.1泛型

    泛型类定义泛型类可以规定传入对象 泛型类 和泛型方法 泛型接口 如果实现类也无法确定泛型 可以在继承类中确定泛型:

  • 【Swift】泛型常见使用

    1、Swift泛型4种 泛型函数泛型类型泛型协议泛型约束 2、泛型约束3种 继承约束:泛型类型 必须 是某个类的子...

网友评论

      本文标题:泛型

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