11 浏览
0 Comments

如果List是List的子类型,那么上述代码将是合法的,因为Java在编译时会删除大部分泛型的魔力。(这是否是一个好决定是另一个话题)。

但是,这样的设计会导致类型安全性问题。考虑以下示例:

public void addNewAToList(List list) {
    list.add(new A());
}
public static void main(String[] args) {
    List listB = new LinkedList();
    addNewAToList(listB);       // <-- 编译错误
    for (B b : listB) {         // <-- 否则:列表中会有一个A。
        System.out.println(b);
    }
}

在上述代码中,我们尝试将一个A对象添加到一个List中,这是不合法的。如果允许List是List的子类型,那么编译器将无法在编译时检测到这个错误。

因此,Java不允许将List视为List的子类型。这就是为什么A->B不会导致List->List的原因。

解决这个问题的一种方法是使用通配符(wildcard)。通过使用通配符,我们可以灵活地处理不同类型的列表。

例如,可以将方法定义为接受List,这意味着它可以接受任何类型为A或A的子类型的列表。然后,我们可以在方法中安全地添加A或其子类型的对象,而不会破坏类型安全性。

以下是修改后的代码示例:

public void addNewAToList(List list) {
    list.add(new A());  // <-- 编译错误
}
public static void main(String[] args) {
    List listB = new LinkedList();
    addNewAToList(listB);
    for (B b : listB) {
        System.out.println(b);
    }
}

在上述代码中,我们使用了通配符来表示列表的类型,并且在方法中尝试将一个A对象添加到列表中。这时,编译器会报错,因为它无法确定列表的确切类型,从而保证了类型安全性。

通过使用通配符,我们可以在不破坏类型安全性的情况下处理不同类型的列表。这是解决A->B不导致List->List的一种方法。

0