结合原始类型和通用方法 [英] Combining Raw Types and Generic Methods

查看:80
本文介绍了结合原始类型和通用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  ArrayList< String>下面是一个问题,第一个代码清单编译得很好(JDK 1.6 | JDK 1.7) a = new ArrayList< String>(); 
String [] s = a.toArray(new String [0]);

但是,如果我声明 List 参考作为原始类型:

  ArrayList a = new ArrayList(); 
String [] s = a.toArray(new String [0]);

我得到一个编译器错误,指出 String [] 是必需的,但找到 Object [] 。这意味着我的编译器将通用方法解释为返回 Object [] ,尽管接收到 String [] 作为它的参数。



我对进行了双重检查toArray(myArray)方法签名:

 < T> T [] toArray(T [] a); 

因此,它是一个参数化方法,其类型参数< T> code>与列表(即< E> )没有任何关系。

我不知道如何在这里使用原始类型影响使用独立类型参数的参数化方法的评估。


  • 有没有人知道为什么这段代码不能编译?

  • 有没有人知道有何记载此行为的参考?
  • div>

    这并不完全符合您的期望,但如果您以原始形式引用泛型类,则会失去对实例成员使用泛型的能力。它不限于泛型方法,请检查这一点:

      public class MyContainer< T> {

    公开列表< String>字符串(){
    返回Arrays.asList(a,b);
    }
    }

    MyContainer container = new MyContainer< Integer>();
    列表< String> strings = container.strings(); //给出未经检查的警告!

    这是JLS的相关部分( 4.8 ):


    未从其超类继承的原始类型C的构造函数(第8.8节),实例方法(第8.4节,第9.4节)或非静态字段(第8.3节)M的类型或超接口是原始类型,对应于在对应于C的泛型声明中删除其类型的原始类型。



    Here's a question, this first code listing compiles just fine (JDK 1.6 | JDK 1.7):

    ArrayList<String> a = new ArrayList<String>();
    String[] s = a.toArray(new String[0]);
    

    However, if I declare the List reference as a raw type:

    ArrayList a = new ArrayList();
    String[] s = a.toArray(new String[0]);
    

    I get a compiler error saying the String[] is required but Object[] was found.

    This means my compiler is interpreting the generic method as returning Object[] despite of receiving a String[] as its argument.

    I doubled-checked the toArray(myArray) method signature:

    <T> T[] toArray(T[] a);
    

    Therefore it is a parameterized method whose type parameter <T> has no relation whatsoever with that of the List (i.e. <E>).

    I have no idea how using a raw type here affects the evaluation of parameterized methods using independent type parameters.

    • Does anyone has any idea why this code does not compile?
    • Does anybody knows any reference where this behavior is documented?

    解决方案

    It's not exactly what you'd expect, but if you refer to a generic class in raw form, you lose the ability to use generics in any way for instance members. It's not restricted to generic methods either, check out this:

     public class MyContainer<T> {
    
         public List<String> strings() {
             return Arrays.asList("a", "b");
         }
     }
    
     MyContainer container = new MyContainer<Integer>();
     List<String> strings = container.strings(); //gives unchecked warning!
    

    This is the relevant part of the JLS (4.8):

    The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

    这篇关于结合原始类型和通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆