泛型

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

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

    • 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, Object> favorites = new HashMap<>();
    
        public  void putFavorite(Class type, T instance) {
            favorites.put(Objects.requireNonNull(type), type.cast(instance));
        }
    
        public  T getFavorite(Class 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());
        }
    }
    

    你可能感兴趣的:(泛型)