java遗珠之泛型七大限制

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lastsweetop/article/details/83030629

不能使用原始类型实例化泛型类型

参数化类型如下:

public class OrderedPair<K, V> implements Pair<K, V> {

    private K key;
    private V value;

    public OrderedPair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }

    public V getValue() {
        return value;
    }

    public void setKey(K key) {
        this.key = key;
    }

    public void setValue(V value) {
        this.value = value;
    }

不能用原始类型代替K和V

OrderedPair<int, char> p1 = new OrderedPair<>(1, 'a'); // compile-time error

仅仅非原始类型允许替代

OrderedPair<Integer, Character> p1 = new OrderedPair<>(1, 'a');

注意后面只是进行了自动封包

不能创建类型参数的实例

不能创建类型参数的实例,会产生编译错误

public static <E> void append(List<E> list) {
        E elem = new E();  // compile-time error
        list.add(elem);
    }

变通一下,可以通过反射来实现目的

public static <E> void append(List<E> list,Class<E> eClass) throws IllegalAccessException, InstantiationException {
        E elem = eClass.newInstance();  // compile-time error
        list.add(elem);
    }

可以如下调用

public static void main(String[] args) {
        List<String> strings=new ArrayList<>();
        try {
            append(strings,String.class);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

不能定义类型为类型参数的静态字段

类的静态变量是所以非静态对象共享的,因此类型参数的静态字段是禁止的,比如:

public class MobileDevice<T> {
    private static T os;

    // ...
}

如果允许,想象一下下面的代码

MobileDevice<Smartphone> phone = new MobileDevice<>();
MobileDevice<Pager> pager = new MobileDevice<>();
MobileDevice<TabletPC> pc = new MobileDevice<>();

是不是彻底不知道T到底是啥了。

不能在参数化类型上使用强制转换和instanceof

因为编译器会擦除泛型代码的所有类型参数,你不能证实在运行时泛型类型的参数类型到底是什么

public static <E> void rtti(List<E> list) {
    if (list instanceof ArrayList<Integer>) {  // compile-time error
        // ...
    }
}

参数化类型在运行传入到方法中

S = { ArrayList<Integer>, ArrayList<String> LinkedList<Character>, ... }

运行时无法追踪参数类型,它不知道 ArrayList<Integer>
ArrayList<String>
有啥区别。

最多能确定无边界的通配符是个 ArrayList
,比如:

public static void rtti(List<?> list) {
    if (list instanceof ArrayList<?>) {  // OK; instanceof requires a reifiable type
        // ...
    }
}

同样,你也不能做类型转换,除非是无边界通配符的参数化类型。

List<Integer> li = new ArrayList<>();
List<Number>  ln = (List<Number>) li;  // compile-time error

但是还有一些情况下,编译器知道怎么转换:

List<String> l1 = new ArrayList<>();
ArrayList<String> l2 = (ArrayList<String>)l1;  // OK

不能创建参数化类型的数组

不能创建参数化类型的数组,下面代码编译不过

List<Integer>[] arrayOfLists = new List<Integer>[2];  // compile-time error

下面的代码很明显会运行异常

Object[] strings = new String[2];
strings[0] = "hi";   // OK
strings[1] = 100;    // An ArrayStoreException is thrown.

创建参数化类型其实和上面的代码是类似的

Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                            // but the runtime can't detect it.

不能创建,捕获或抛出参数化类型的对象

泛型不能直接或间接扩展 Throwable
,下面的例子都会编译错误

// Extends Throwable indirectly
class MathException<T> extends Exception { /* ... */ }    // compile-time error

// Extends Throwable directly
class QueueFullException<T> extends Throwable { /* ... */ // compile-time error

方法也不能catch类型参数的实例

public static <T extends Exception, J> void execute(List<J> jobs) {
    try {
        for (J job : jobs)
            // ...
    } catch (T e) {   // compile-time error
        // ...
    }
}

但是可以通过类型参数抛出异常

class Parser<T extends Exception> {
    public void parse(File file) throws T {     // OK
        // ...
    }
}

不能重载类型擦除后原生类型相同的方法

擦除后参数签名就一样了,自然不能重载

public class Example {
    public void print(Set<String> strSet) { }
    public void print(Set<Integer> intSet) { }
}

原文 

https://blog.csdn.net/lastsweetop/article/details/83030629

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » java遗珠之泛型七大限制

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址