Java 泛型精要

本篇记录了Java泛型的部分要点,内容主要参考《effective java》中泛型一章,文章将提纲挈领列举Joshua Bloch对Java泛型的使用建议。

一、新代码中不要用原始类型(rawtype)

原因不赘述了。只是有几点需要注意:

1、List与List< Object>

  • List : 逃避了类型检查
  • List< Object>:告知编译器,它能够持有任何类型的对象
  • 泛型有子类型化(subTyping)的规则,List< String> 是原生态类型List 类型的一个子类型,但不是参数化类型List < Object>的子类型
    • 可将List< String> 传给List 类型的参数,但是不能将List< String> 传给List< Object> 类型的参数,所以List是失去了类型检查,而List< Object>并没有。

下面来看几个对应的demo:

//  demo 1 :测试类型List 与List<String>
  public static void main(String[] args) {

        List<String> stringList = new ArrayList<>();
        unsafeAdd(stringList, 1L);
        //java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
        String s = stringList.get(0); 
    }

    // 躲过了类型检查
    private static void unsafeAdd(List stringList, Object o) {
        stringList.add(o);
    }

// demo2: 测试List<String> 与List<Object>的关系
  public static void main(String[] args) {

        List<String> stringList = new ArrayList<>();
        // List<string> 并不是 List<Object> 的子类型,所以此处编译不通过
        unsafeAdd(stringList, 1L);
    }

    // 躲过了类型检查
    private static void unsafeAdd(List<Object> stringList, Object o) {
        stringList.add(o);
    }

2、Set与Set< ?> 、Set< Object>

Set< ?>:
如果不确定或者不关心实际的类型参数,可以无限制通配符.Set< ?>读作“某个类型的集合”,表示可以持有任意一种类型的集合。

Set< Object>:
可以持有任意类型的集合。

demo1:
   static void add(Set<?> set, Object o) {
        // Error:(34, 12) java: 对于add(java.lang.Object), 找不到合适的方法
//        方法 java.util.Set.add(capture#1, 共 ?)不适用
//                (参数不匹配; java.lang.Object无法转换为capture#1)
        set.add(o);
    }
    
demo2:
 static Object get(Set<?> set) {
        Object next = set.iterator().next();
        return next;
    }

可见Set< ?> 里,是无法放入任何元素的(不讨论null),而且拿出来的元素都是Object类型

可见Set< ?> 里,是无法放入任何元素的(不讨论null),而且拿出来的元素都是Object类型

可见Set< ?> 里,是无法放入任何元素的(不讨论null),而且拿出来的元素都是Object类型

重要的事情,我们说三遍!

3、必须使用raw type 的场合

  • 在类字面量中必须使用raw type ,即List.class
  • 使用instanceOf 操作符时必须使用raw type
 /*利用泛型来使用instanceOf 的推荐方法,一旦返现这collection是 List,就必须转为
    * List<?> ,而不是List。这是受检转换,不会导致编译时警告*/
    static void instance(Collection collection) {
        if (collection instanceof List) {
            List<?> list = (List<?>) collection;
        }
    }

4、标准的泛型术语

泛型这块的各种翻译极易混淆,需要注意:
List< String> --> 参数化类型–> parameterized type
String --> 实际参数类型 --> Actual type parameter
List< E> -->泛型 -->generic type
List< ?> --> 无限制通配符类型–>Unbounded wildcard type
List< ? extends Number> -->有限制通配符类型 -->Bounded wildcard type
List --> 原型 --> raw type
< T extends Number> -->有限制类型参数
<T extends Comparable< T>> --> Recursive type bound --> 递归类型限制
static < E> List< E> asList(E[] a) --> generic method --> 泛型方法

二、

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值