为什么List不能作为List接受?
13 浏览
0 Comments

为什么List不能作为List接受?

考虑下面的方法doSomething(List),它接受List作为参数。

private void doSomething(List list) {
    // 执行某些操作
}

现在考虑下面的代码片段,它试图调用doSomething(),我试图将List传递给doSomething()

List objectList;
List stringList;
doSomething(stringList); // 编译错误,类型不兼容
doSomething(objectList); // 正常工作

甚至下面的代码也会引发编译错误

objectList = stringList;  // 编译错误,类型不兼容

我的问题是为什么List不能传递给接受List的方法?

0
0 Comments

在Java中,这个泛型问题可能对于那些对泛型不太熟悉的人来说可能会感到困惑,因为乍一看,似乎String是Object,所以List<String>可以在需要List<Object>的地方使用,但这是错误的。这将导致编译错误。

如果进一步思考,这是有道理的,因为List<Object>可以存储任何东西,包括String、Integer等,但List<String>只能存储String。

问题不完全在于调用者可以存储任何类型的对象,真正的问题是,如果允许这样做,调用者将无法确定是否有一个String实例,因此必须像在没有泛型的时代一样处理它(使用instanceof操作符)。

解决这个问题的方法之一是使用通配符。可以使用`List`来表示可以存储任何类型的对象的列表,包括String。这样,就可以将`List`赋值给`List`,但是不能将`List`赋值给`List`。

另一个解决方法是在需要使用`List`的地方使用`List`来接受`List`。这样,调用者就可以传递一个`List`给方法,而不会导致编译错误。

总之,`List`不能作为`List`的替代,因为它只能存储String类型的对象,而不是任何类型的对象。

0
0 Comments

List is not acceptable as List because it would violate type safety. The reason for this is that if it were allowed, it would be possible to add an object of the wrong type into the list.

For example, consider the following code:

private void doSomething(List list) {
    list.add(new Integer(123)); // Should be fine, it's an object
}
List stringList = new ArrayList();
doSomething(stringList); // If this worked....
String s = stringList.get(0); // ... you'd receive a ClassCastException here

In this code, the method `doSomething` takes a List as a parameter. It adds an Integer object to the list, which is allowed because Integer is a subclass of Object.

However, if it were possible to pass a List to this method, the code would compile without error. But when we try to retrieve the element from the list as a String, a ClassCastException would occur because the element is actually an Integer.

To maintain type safety, Java does not allow List to be treated as a List. This ensures that only objects of the correct type are added to the list, preventing potential runtime errors.

To solve this issue, you can use wildcard generics. Instead of using List, you can use List as the parameter type for the method. This allows any type of list to be passed in, but you cannot add any elements to the list inside the method. The modified code would look like this:

private void doSomething(List list) {
    // list.add(new Integer(123)); // This would cause a compilation error
}
List stringList = new ArrayList();
doSomething(stringList); // This works fine
String s = stringList.get(0); // No ClassCastException here

By using List instead of List, you can pass in any type of list without violating type safety. However, you need to be aware that you cannot add any elements to the list inside the method.

0
0 Comments

List<String>不是List<Object>的子类型,所以List<String>不能被赋值给List<Object>

解决方法是使用通配符来实现类型转换,可以使用((List<Object>)(List<?>) stringList)来调用方法。

0