通用变量的编译器警告解决方案

TJR*_*TJR 5 java generics variadic-functions

这个博客的一个难题.与SO1445233相似.

给出以下源列表,解释为什么编译器在调用list方法时产生警告,并提供解除删除警告的解决方案而不诉诸@SuppressWarnings注释.

public class JavaLanguagePuzzle3 {
  public static void main(String[] args) {
    list("1", 2, new BigDecimal("3.5"));
  }  
  private static <T> List<T> list(T... items) {
    return Arrays.asList(items);
  }
}
Run Code Online (Sandbox Code Playgroud)

警告:

Type safety: A generic array of Object&Serializable&Comparable<?> is created for a varargs parameter
Run Code Online (Sandbox Code Playgroud)

TJR*_*TJR 2

这是我的想法。

public static interface Foo extends Serializable, Comparable<Object> {
}

public static void main(String[] args) {
  // Problem: Unsafe: varargs has generic type
  implicitList("1", 2, BigDecimal.valueOf(3.5)); // warning: generic vararg

  // Solution 1: Constrain type of varags explicitly through generics
  explicitList1(Object.class, "1", 2, BigDecimal.valueOf(3.5));
  // However, we could still have the same error from problem
  explicitList1(Foo.class, "1", 2, BigDecimal.valueOf(3.5)); // warning: generic vararg
  // Fix: Make containing class to exact type (PECS) an array is both producer and consumer
  explicitList2(Foo.class, "1", 2, BigDecimal.valueOf(3.5)); // error: incompatible args

  // Solution 2: Override varargs by passing array
  implicitList(new Object[] { "1", 2, BigDecimal.valueOf(3.5) });
}

private static <T> List<T> explicitList1(Class<? extends T> klass, T... items) {
  return Arrays.asList(items);
}

private static <T> List<T> explicitList2(Class<T> klass, T... items) {
  return Arrays.asList(items);
}

private static <T> List<T> implicitList(T... items) {
  return Arrays.asList(items);
}
Run Code Online (Sandbox Code Playgroud)