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

反射问题-类型安全警告

  •  2
  • jax  · 技术社区  · 15 年前
    Class<? extends Algorithm> alg = AlgorithmAllFrom9AndLastFrom10Impl.class   
    Constructor<Algorithm> c = alg.getConstructors()[0];
    

    对于“alg.getconstructors()[0];”我在Eclipse中收到警告

    类型安全:类型的表达式 构造函数需要未选中的转换 符合施工单位要求

    我该怎么解决这个问题?

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

    文件 Class<T>.getConstructors() 揭示问题:

    Constructor<?>[] getConstructors() :请注意,当此方法返回 Constructor<T> 对象(即此类中的构造函数数组),此方法的返回类型为 Constructor<?>[] 而不是 Constructor<T>[] 正如所料。这种信息较少的返回类型是必需的,因为从该方法返回后,可以将数组修改为保留 Constructor 不同类的对象,这将违反 建造师 .

    将此与 Class<T>.getConstructor() 超载:

    Constructor<T> getConstructor(Class<?>... parameterTypes)

    这个重载实际上返回 建造师<T> .

    在你的情况下,既然你 Class<? extends Algorithm> alg , alg.getConstructor(parameterTypes) 返回A Constructor<? extends Algorithm> (顺便说一下,不能安全地投到 Constructor<Algorithm> )

    如果可能,即当您知道参数类型时,您应该始终首选 getConstructor(parameterTypes) getConstructors()[arbitraryIndex] ,因为对于后者,您永远无法完全保证将选择哪个构造函数。根据参数类型进行选择是最具体的,如图所示,对于一般类型信息,也更容易使用编译器。

    如果通过 getConstructors()[0] 您真的打算获取空构造函数,然后简单地执行以下操作:

    Constructor<? extends Algorithm> nullaryConstructor = alg.getConstructor();
    

    总结

    所以你的问题是双重的:

    • getConstructors() 返回A 建设者<?[] ,表示所有类型信息都丢失
    • 即使类型信息没有丢失(例如使用 getconstructor(参数类型) 过载),你仍然只能得到一个 建设者<?扩展算法> 充其量(不是) 构造器<算法> )
      • Class<T>.getConstructor(parameterTypes) 返回A 建造师<T>
      • 在您的例子中,类型参数 T ? extends Algorithm

    也见

    相关问题


    讨论

    不幸的是 getconstructors()。 返回数组,因为如文档中所述,由于数组协变,这强制签名 Constructor<?> ,正在丢失泛型类型信息。数组是可变的这一事实也意味着 getconstructors()。 每次都必须创建一个新的数组实例!

        System.out.println(int.class.getConstructors().length); // prints "0"
        System.out.println(
            int.class.getConstructors() == int.class.getConstructors()
        ); // prints "false"!
    

    理想的 getconstructors()。 应该归还 List<Constructor<T>> ,应该用 Collections.unmodifiableList ;这不仅会保留类型信息,而且 Class<T> 也可以返回相同的 List 对象上的每一个 getconstructors()。 .

    有关此主题的更多讨论,请阅读 有效Java第二版,项目25:喜欢列表到数组 .

        2
  •  0
  •   Andrei Fierbinteanu    15 年前

    实际上没有演员表 Constructor<Algorithm> 我有一个错误。

    一个解决办法是 Constructor<?> c = alg.getConstructors()[0]; 因为这是getconstructors()返回的类型。

    另一个是添加 @SuppressWarnings("unchecked") 到那一行,基本上告诉编译器“我确信这是一个 构造器<算法> “编译器无法分辨。

        3
  •  0
  •   Mark Peters    15 年前

    这个 Constructor 从返回的数组 getConstructors() 具有未绑定的通配符类型参数。你可以使用:

    Constructor<?> c = alg.getConstructors()[0];
    

    我想原因是 getconstructors()。 不绑定它的通配符是因为这将导致一个泛型数组。也许是 getConstructor() 方法更适合您的需要。