tags:

views:

714

answers:

5

This is a simplified version of the code in question, one generic class uses another class with generic type parameters and needs to pass one of the generic types to a method with varargs parameters:

class Assembler<X, Y> {
    void assemble(X container, Y... args) { ... }
}

class Component<T> {
    void useAssembler(T something) {

        Assembler<String, T> assembler = new Assembler<String, T>();

        //generates warning:
        // Type safety : A generic array of T is
        // created for a varargs parameter
        assembler.assemble("hello", something);
    }

}

Is there any correct way to pass along the generic parameter to a varargs method without encountering this warning?

Of course something like

assembler.assemble("hello", new T[] { something });

does not work since you cannot create generic arrays.

+4  A: 

Other than adding @SuppressWarnings("unchecked"), I don't think so.

This bug report has more information but it boils down to the compiler not liking arrays of generic types.

Kevin
Forgot to mention I wanted to avoid @SuppressWarnings("unchecked"). That bug report gives me little hope!
matt b
A: 

It is a very easy problem to solve: Use List<T>!

Arrays of reference type should be avoided.

Tom Hawtin - tackline
Why should they be avoided?
idrosid
this is unavoidable with a varargs parameter, isn't it?
matt b
Arrays of references should be avoided because they are a legacy and play badly with generics (they have incorrect subtyping rules, for instance). `List` is more useful, whereas array is a raw implementation detail.
Tom Hawtin - tackline
There is a proposal for JDK7 to allow the warning suppression to go on the varargs method declaration rather than its usage.
Tom Hawtin - tackline
This completely ignores an important aspect of the author's question - varargs parameters DO create an array, and that generates this warning.
Daniel Yankowsky
I'm agree with @Tom Hawtin - tackline. For details see Bloch <<Effecive Java>> Item 25: Prefer lists to arrays.
Stas
A: 

When workings with arrays of generic type, I am forced to pass a reference to the generic type. With that, I can actually do the generic code, using java.lang.reflect.Array.

http://java.sun.com/javase/6/docs/api/java/lang/reflect/Array.html

KLE
I'm not working with arrays of generic type though, not directly, just varargs of a generic type.
matt b
A: 

You can have overload the methods. This does not solve your problem but it minimizes the number of warnings (and yes, it's a hack!)

class Assembler<X, Y> {
  void assemble(X container, Y a1) { ... }
  void assemble(X container, Y a1, Y a2) { ... }
  void assemble(X container, Y a1, Y a2, Y a3) { ... }
  void assemble(X container, Y a1, Y a2, Y a3, Y a4) { ... }
  void assemble(X container, Y... args) { ... }
}
EA
A: 

Tom Hawtin pointed this out in a comment, but to be more explicit: yes, you can solve this at the declaration-site (rather than the (potentially many) call sites): switch to JDK7.

As you can see in Joseph Darcy's blog post, the Project Coin exercise to select some small incremental language improvements for Java 7 accepted Bob Lee's proposal to allow something like @SuppressWarnings("varargs") at the method side to make this warning go away in situations where it was known to be safe.

This has been implemented in OpenJDK with this commit.

This may or may not be useful to your project (many people wouldn't be happy to switch to a pre-release unstable version of the JVM!) but perhaps it is — or perhaps someone who finds this question later (after JDK7 is out) will find it useful.

Cowan