A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

© 不二晨 金牌黑马   /  2018-10-16 09:36  /  905 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

一、新代码中不要用原始类型(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);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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;
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
可见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;
        }
    }
1
2
3
4
5
6
7
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 --> 泛型方法
---------------------
【转载】
作者:胡小禾
原文:https://blog.csdn.net/qq_3011856 ... 254?utm_source=copy


3 个回复

倒序浏览
奈斯
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马