-1

Reading Robert Sedgewick's book on algorithms, I always see him mention that in java arrays of things that hold other generic things, need to be created like so:

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

So I was wondering if that cast is necessary, because when I do:

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

the compiler still seems to know that the generic type is Bar.

So, is it necessary, and what is the point of it?

Pavel
  • 1
  • 2
  • 14
  • 43
  • 7
    Both operations require unsafe casts. The solution is to use Lists instead of arrays. – Piotr Praszmo Sep 28 '15 at 21:22
  • 2
    possible duplicate of [How to create a generic array?](http://stackoverflow.com/questions/18581002/how-to-create-a-generic-array) – Piotr Praszmo Sep 28 '15 at 21:32
  • 1
    @Banthar that's not a duplicate, and I didn't ask about lists of lists. I asked specifically about arrays. – Pavel Sep 28 '15 at 21:33
  • @paulpaul1076 it's not about the specifics, it's about the idea; it's a duplicate one way or another: http://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java?rq=1 , http://stackoverflow.com/questions/linked/529085?lq=1 etc. –  Sep 28 '15 at 21:35

3 Answers3

1

You should use Foo<Bar>[] foo = new Foo[N];.

You may get a warning like:

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

which you can hide using @SuppressWarnings("unchecked"):

@SuppressWarnings("unchecked")
Foo<Bar>[] foo = new Foo[N];
Andreas
  • 138,167
  • 8
  • 112
  • 195
-1

cast is to enforce type safety. first line doesn't compile, because the type is wrong. second one compiles fine, but most probably will error out during runtime.

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> {}
}
ilj
  • 827
  • 6
  • 17
-3

There is really no difference between those two. Both require unchecked casts. You should not mix arrays and generics. Unchecked casts undermine the whole purpose of generics. It will lead to ClassCastExceptions in unexpected places. For example:

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
}
Piotr Praszmo
  • 16,785
  • 1
  • 51
  • 60
  • 3
    Because of type erasure, you can always do bad things with bad casts. That is not specific to arrays, since you can do the same with a `List`, so the argument is not really sound. – Andreas Sep 28 '15 at 21:50
  • @Andreas There is no way to do this without unchecked casts. You should avoid mixing arrays and generics because it requires unchecked casts. – Piotr Praszmo Sep 28 '15 at 21:55
  • @Banthar so what? There are unchecked casts in the implementation of ArrayList<> and in plenty of other places. There's no way to fully avoid them. – Pavel Sep 28 '15 at 22:04
  • @paulpaul1076 You can avoid them in this case. – Piotr Praszmo Sep 28 '15 at 22:08
  • Avoid them by relying on the fact that the person who wrote the implementation of ArrayList wrote SuppressWarnings("unchecked")? – Pavel Sep 28 '15 at 22:10
  • Yes. Unchecked casts were allowed partially so ArrayList could be implemented. ArrayList was carefully designed so unsafe arrays do not leak outside and there is no heap pollution. By using ArrayList, you do not have to worry about it in your code. – Piotr Praszmo Sep 28 '15 at 22:21