【问题标题】:Should I 'new List[N]' or '(List<Integer>[])new List[N]' in java, when I want an array of lists of integers?当我想要一个整数列表数组时,我应该在 java 中使用 'new List[N]' 还是 '(List<Integer>[])new List[N]' ?
【发布时间】:2015-09-28 21:20:03
【问题描述】:

阅读 Robert Sedgewick 关于算法的书,我总是看到他提到,在 java 中包含其他通用事物的事物数组需要像这样创建:

Foo<Bar>[] foo = (Foo<Bar>[])new Foo[N];

所以我想知道该演员表是否有必要,因为当我这样做时:

Foo<Bar>[] foo = new Foo[N];

编译器似乎仍然知道泛型类型是 Bar。

那么,有必要吗,有什么意义呢?

【问题讨论】:

标签: java arrays generics


【解决方案1】:

你应该使用Foo&lt;Bar&gt;[] foo = new Foo[N];

您可能会收到如下警告:

Type safety: The expression of type Foo[] needs unchecked conversion to conform to Foo<Bar>[]

您可以使用 @SuppressWarnings("unchecked") 隐藏它:

@SuppressWarnings("unchecked")
Foo<Bar>[] foo = new Foo[N];

【讨论】:

  • Foo&lt;Bar&gt;[] foo = new Foo[N]可以发出警告时,他为什么要使用?
  • @akhil_mittal 另一个中的演员是多余的,无论如何都不会阻止警告。
  • 你可以隐藏警告,但你应该这样做吗?
  • @Andreas 是的。警告是让您知道该数组并不像应有的那样安全。如果使用数组的代码写得好,就可以了。
  • @paulpaul1076 只是我的另一个自我。 ;-)
【解决方案2】:

cast 是为了强制类型安全。第一行无法编译,因为类型错误。第二个编译得很好,但很可能会在运行时出错。

public class Test {

    public static void main(String[] args) {
        Foo<Bar>[] foo1 = (Foo<Bar>)new Foo[] {new Foo<String>()};
        Foo<Bar>[] foo2 = new Foo[] {new Foo<String>()};
    }

    static class Bar {}
    static class Foo<T> {}
}

【讨论】:

  • 在第一行中,您写的是 (Foo) 而不是 (Foo[])。
  • 问题中的两行都编译得很好。
【解决方案3】:

这两者之间确实没有区别。两者都需要未经检查的演员表。你不应该混合使用数组和泛型。未经检查的强制转换破坏了泛型的整个目的。它会在意想不到的地方导致 ClassCastExceptions。例如:

static class Foo<T> {
    T value;
    public Foo(T v) {
        value = v;
    }
}

public static void main(final String[] args) throws IOException {
    @SuppressWarnings("unchecked")
    Foo<Boolean>[] foo = new Foo[1];

    ((Object[])foo)[0] = new Foo<Integer>(0);
    foo[0].value.booleanValue(); // runtime error will occur here
}

【讨论】:

  • 由于类型擦除,你总是可以用糟糕的演员表做坏事。这并不特定于数组,因为您可以对 List 执行相同的操作,因此该论点并不合理。
  • @Andreas 如果没有未经检查的演员表,就无法做到这一点。您应该避免混合使用数组和泛型,因为它需要未经检查的强制转换。
  • @Banthar 那又怎样?在 ArrayList 和许多其他地方的实现中存在未经检查的强制转换。没有办法完全避免它们。
  • @paulpaul1076 在这种情况下你可以避免它们。
  • 依靠编写 ArrayList 实现的人写了 SuppressWarnings("unchecked") 来避免它们?
猜你喜欢
  • 1970-01-01
  • 2014-01-03
  • 1970-01-01
  • 2017-09-13
  • 2015-05-29
  • 1970-01-01
  • 2011-10-21
  • 2019-03-15
  • 2020-03-15
相关资源
最近更新 更多