java:使用Raw类型作为方法参数会删除参数成员中的所有参数化类型信息

时间:2009-11-04 17:05:24

标签: java generics

请解释一下为什么如果我在方法test()中使用原始类型A,我的类型列表上的get()方法返回一个Object而不是B。:

public class test
{
    public class B{}
    public class C{}

    public class A<T extends C>
    {
        private List<B> aBList;

        public List<B> mGetBList()
        {
            return aBList;
        }
    }

    public test(A pA) // Use of raw type - this is bad, I know!
    {
        B lB = pA.mGetBList().get(0); // Compile error: Type mismatch: 
                                      // cannot convert from Object to test.B   

    }
}

如果我宣布

public test(A<?> pA)

get()方法按预期返回B.

4 个答案:

答案 0 :(得分:2)

“医生,当我这个时会很痛。”

避免像瘟疫这样的原始类型。

答案 1 :(得分:1)

+1有趣的测试用例。

看起来擦除会删除所有内容,所以在这种情况下,你最终会删除。

public List mGetBList()

并且List的删除将导致public Object get( int ),当然,这不能分配给B

如果方法签名中不需要原始类型,请使用您提供的通用表单,否则将对象强制转换为B

B lB = (B) pA.mGetBList().get(0);

答案 2 :(得分:0)

在方法测试中对参数pa进行decalare时,不包含任何参数(包括通配符)。因此,列表保存在包含对象列表的变量中,因此当您尝试从列表中提取元素时,您将获得一个对象,因此您必须将其强制转换为所需的类型,在本例中为B. / p>

使用通配符时,会告诉编译器不将列表提升为包含保存Object的列表的varibale。它被告知列表中的内容属于“未知类型”,并且要保持独立。然后由程序员决定在提取元素时将其分配给合适的varibale,而不使用强制转换。

答案 3 :(得分:0)

我一直在做一些围绕ang的挖掘发现了这一点。

http://java.sun.com/docs/books/tutorial/extra/generics/legacy.html

基本上,擦除删除(或删除)所有泛型类型信息。抛出尖括号之间的所有类型信息,因此,例如,像List这样的参数化类型被转换为List。 类型变量的所有剩余用法都被类型变量的上限(通常是Object)替换。

如果他们的意思是&lt; T扩展C&gt;,C将是上限,然后因为只有B是aBlist的类型varibable,那么它的上限将是Object。

Anway希望这会有所帮助(请不要再把我标记下来了。)