List和List<之间有什么区别?>, List<T>, List<E>, List<Object>?

1. 列表

List:是一个原始类型,因此不是类型安全的。它只会在强制转换错误时生成运行时错误。当强制转换错误时,我们希望出现编译时错误。不建议使用。

2. 列表< ?>

列表< ?>是一个无界通配符。但我不确定这是干什么用的?我可以打印一个List<?>无问题:

public static void test(List<?> list){
    System.out.println(list);   // Works
}

为什么我不能向List<?>?

public static void test(List<?> list){
    list.add(new Long(2));     // Error
    list.add("2");             // Error
    System.out.println(list);
}

3. 目前居住;rolelabel T >

public static void test(List<T> list){   // T cannot be resolved
    System.out.println(list);
}

我不明白这个语法。我看到了类似这样的东西,它起作用了:

public <T> T[] toArray(T[] a){
    return a;   
}

有时,我看到<T>,或<E>,或<U>, <T,E>。它们都是一样的还是代表着不同的东西?

4. List <物体>

这给出了错误“the method test(List<Object>) is not applied for the argument List<String>”:

public static void test(List<Object> list){
    System.out.println(list);
}

如果我尝试这样做,那么我得到“不能从列表<字符串>到列表<对象>”:

test((List<Object>) names);

我很困惑。字符串是对象的子类,所以为什么List<String>不是List<Object>的子类?


当前回答

你是对的:String是Object的子集。由于String比Object更“精确”,您应该强制转换它以将其用作System.out.println()的参数。

其他回答

最后一部分: 虽然String是Object的子集,但是List<String>并不是继承自List<Object>。

符号List<?>的意思是“一个列表的东西(但我不是说什么)”。因为测试中的代码适用于列表中的任何类型的对象,所以这是一个正式的方法参数。

使用类型参数(如要点3)需要声明类型参数。Java语法是将<T>放在函数前面。这完全类似于在使用方法体中的名称之前向方法声明形式参数名称。

关于List<Object>不接受List<String>,这是有意义的,因为String不是Object;它是Object的子类。修复方法是声明公共静态无效测试(List<?扩展对象> set) ....但是extends Object是多余的,因为每个类都直接或间接地扩展Object。

不能将List<String>强制转换为List<Object>的原因是,它将允许您违反List<String>的约束。

考虑以下场景:如果我有一个List<String>,它应该只包含String类型的对象。(这是最后一节课)

如果我可以将其转换为List<Object>,那么这就允许我将Object添加到该列表中,从而违反了List<String>的原始契约。

因此,一般来说,如果类C继承自类P,你不能说GenericType<C>也继承自GenericType<P>。

注意:我在之前的回答中已经评论过这一点,但我想在此展开。

1)正确

2)你可以认为这是一个“只读”列表,在那里你不关心项目的类型。可以被返回列表长度的方法使用。

3) T、E和U是相同的,但人们倾向于使用例如T表示类型,E表示元素,V表示值,K表示键。编译的方法说它获取了一个特定类型的数组,并返回了一个相同类型的数组。

你不能把橘子和苹果混在一起。如果可以将字符串列表传递给需要对象列表的方法,则可以将Object添加到String列表中。(并不是所有对象都是字符串)

我建议阅读Java谜题。它很好地解释了声明中的继承、泛型、抽象和通配符。 http://www.javapuzzlers.com/