代码之家  ›  专栏  ›  技术社区  ›  Thilo

警告:object&serializable&comparable的泛型数组<?>为varargs参数创建

  •  2
  • Thilo  · 技术社区  · 14 年前

    如果我使用不同类的对象调用(泛型)varargs方法,我会得到一个有趣的警告:

    List<?> result =  Arrays.asList("1", 1);
    

    为varargs参数创建了一个可比较对象和可序列化对象的通用数组。

    我可以通过强制转换到公共接口或类来消除警告,

    List<Serializable> result = asList((Serializable) "1", (Serializable) 1);
    

    但是什么呢? Object&Serializable&Comparable<?> 意思是?它是否也可以用于方法签名上的泛型类型注释(例如 extends super )?

    3 回复  |  直到 10 年前
        1
  •  3
  •   Community CDub    7 年前

    班级 Object 以及接口 Comparable Serializable 类的父类型 Integer String 有共同之处。

    由于泛型中的类型擦除和数组的协方差,泛型和数组不能很好地相互混合。方法 Arrays#asList 以VARARGS作为输入,而在Java中,VARARGS内部用数组实现。因此发出警告。(你可以在Josh Bloch的JavaJavaJava中阅读更多关于这方面的内容。)

    接下来是第二个问题, <Object & Comparable<Whatever> & Serializable> 可在方法签名中用于指定类型参数的约束。(见 this answer 但是Java不允许在泛型类型注释中使用此类类型。

    换句话说,以下内容是有效的:

    public static void <A extends Comparable<A> & Serializable> meth(A a);
    

    但以下不是:

    List<Serializable & SomeOtherInterface> list = ...;
    
        2
  •  1
  •   Emil    14 年前

    我认为,因为所有对象类型都是可序列化和可比较的(字符串和整数),所以编译器表示数组中的所有元素都将具有对象类型并实现可序列化和可比较的接口。

    我怀疑串行化和可比性在Java代码中可以正常使用,您通常可以正常执行它们并接受相同的警告:

    public class ComparableAndSerializableClass implements Comparable<ComparableAndSerializableClass>, Serializable{
    
        public static void main(String[] args) {
            List<?> result = Arrays.asList( "1", 1, new ComparableAndSerializableClass());
            for (Object comp : result) {
                System.out.println(comp.getClass());
            }
        }
    
        @Override
        public int compareTo(ComparableAndSerializableClass o) {
            return 0;
        }
    }
    
        3
  •  0
  •   Aaron Digulla    10 年前

    如果你有一个像 Foo<...> ,然后可以使用helper方法调用 Arrays.asList() 为你:

    public static List<Foo<?>> asList( Foo<?> ... foos ) {
        return Arrays.asList( foos );
    }
    

    Java编译器将为VARARGS参数创建一个通用数组,然后您可以在调用中安全地使用它。 数组 . 如果你想要一切 Foo 要具有相同的内部类型:

    public static <T> List<Foo<T>> asList( Foo<T> ... foos ) {
        return Arrays.asList( foos );
    }