Is it possible to solve the "A generic array of T is created for a varargs parameter" compiler warning?

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.


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.


If you're after a fluent-type interface, you could try the builder pattern. Not as concise as varargs but it is type safe.

A static generically-typed method can eliminate some of the boilerplate when using the builder, while retaining the type safety.

The builder

public class ArgBuilder<T> implements Iterable<T> {

    private final List<T> args = new ArrayList<T>();

    public ArgBuilder<T> and(T arg) {
        args.add(arg);
        return this;
    }

    @Override
    public Iterator<T> iterator() {
        return args.iterator();
    }

    public static <T> ArgBuilder<T> with(T firstArgument) {
        return new ArgBuilder<T>().and(firstArgument);
    }
}

Using it

import static com.example.ArgBuilder.*;

public class VarargsTest {

    public static void main(String[] args) {
        doSomething(new ArgBuilder<String>().and("foo").and("bar").and("baz"));
        // or
        doSomething(with("foo").and("bar").and("baz"));
    }

    static void doSomething(Iterable<String> args) {
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

Tags:

Java

Generics