代码之家  ›  专栏  ›  技术社区  ›  jumar

Java:Sube Type作为方法参数使用参数成员中的所有参数化类型信息

  •  4
  • jumar  · 技术社区  · 15 年前

    请解释为什么如果我在method test()中使用原始类型A,那么类型列表中的get()方法将返回一个对象而不是一个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 回复  |  直到 15 年前
        1
  •  1
  •   Alexander Pogrebnyak    15 年前

    +1用于有趣的测试用例。

    看起来擦除会擦除所有内容,所以在本例中,您最终会得到。

    public List mGetBList()

    删除 List 会导致 public Object get( int ) 当然,不能分配给 B .

    如果方法签名中不需要原始类型,请使用已提供的泛型形式,否则将对象强制转换为

    B lB = (B) pA.mGetBList().get(0);
    
        2
  •  2
  •   Kevin Bourrillion Gergely    15 年前

    “医生,我这样做的时候很疼 他说:“我想,我是一个很好的朋友。”

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

        3
  •  0
  •   chrisg    15 年前

    当您在方法测试中去掉参数pa时,不包括任何参数(包括通配符)。因此,列表被保存在一个包含对象列表的变量中,因此当您试图从列表中提取元素时,您会得到一个对象,因此您必须将其转换回所需的类型,在本例中是B。

    当使用通配符时,会告诉compliler不要将列表提升为包含列表保持对象的变量。据告知,列表中的内容属于“未知类型”,应单独保存。然后由程序员来确保在提取元素时,它被分配给一个合适的变量,而不使用强制转换。

        4
  •  0
  •   chrisg    15 年前

    我在附近挖了些洞,发现了这个。

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

    基本上,擦除消除(或擦除)所有通用类型信息。尖括号之间的所有类型信息都被抛出,因此,例如,一个类似于列表的参数化类型被转换为列表。 类型变量的所有剩余使用都被类型变量(通常是对象)的上界替换。

    如果上界表示t扩展c>,那么c就是上界,因为只有b是ablist的变量类型,那么它的上界就是object。

    安威希望这有帮助(请不要再把我记下来)。