泛型

作者: 李军_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());
        }
    }
    

    相关文章

      网友评论

          本文标题:泛型

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