java - 类中 getConstructors() 中的通用类型

标签 java generics reflection

在通用类中 Class<T> 方法 getConstructors() 具有未知泛型类型参数的返回类型而不是 T .原因在 javadoc 中有解释。

Note that while this method returns an array of Constructor<T> objects (that is an array of constructors from this class), the return type of this method is Constructor<?>[] and not Constructor<T>[] as might be expected. This less informative return type is necessary since after being returned from this method, the array could be modified to hold Constructor objects for different classes, which would violate the type guarantees of Constructor<T>[].

我和我的一位同事试图理解这种解释。在我们的理解中,他们基本上是在说它是未知的泛型类型,因为某些调用者可以将其他 Constructor对象放入该数组。我们做对了吗?如果是这样,为什么有人会以这种方式设计 API。使用特定类型并相信程序员正确使用数组不是更好吗?对我们来说,这听起来有点像“我们正在制作一个更糟糕的 API,因为使用它的程序员可能会尝试一些愚蠢的事情”。我们的谬误在哪里?

最佳答案

Ashu Pachauri 在评论中提到的一点(即返回数组是为了向后兼容)当然是有效的。通常,数组和泛型不能很好地协同工作。 (有关证据,请查找与 "Generic Arrays" 相关的所有 stackoverflow 问题 ...)

此外,还有一条规则,即 API 应该易于使用并且难以滥用。在这种情况下,这与 Principle of least astonishment 有关: 使用此方法获取构造函数的人可以对返回的数组执行完全合法的操作序列,并最终收到意想不到的 ClassCastException。 .所以可以说一个 Constructor<?>[] 的事实返回数组旨在实现“快速失败”行为。

一个说明性的例子:

import java.lang.reflect.Constructor;

public class GetConstructorsReturnType
{
    public static void main(String[] args) throws Exception
    {
        // This causes a warning, due to the cast, but imagine
        // this was possible
        Constructor<DerivedA> constructorsA[] =
            (Constructor<DerivedA>[])DerivedA.class.getConstructors();

        // The following lines are valid due to the subtype
        // relationship, but would not be valid if constructorsA
        // was declared as "Constructor<?>"
        Constructor<? extends Base> constructors[] = constructorsA;
        constructors[0] = DerivedB.class.getConstructor();

        // This causes a ClassCastException (and would also not
        // be possible constructorsA was declared as "Constructor<?>"
        DerivedA instance = constructorsA[0].newInstance();
    }
}
class Base
{
}
class DerivedA extends Base
{
    public DerivedA()
    {
    }
}
class DerivedB extends Base
{
    public DerivedB()
    {
    }
}

关于java - 类中 getConstructors() 中的通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24511789/

相关文章:

ruby - 如何获取 Ruby 类中未定义方法的列表?

java - 对 com.amazonaws :aws-lambda-java-events:jar is missing) 进行无服务器部署到 aws ('dependencies.dependency.version' 时,maven 构建错误

java - 使用 ColdFusion 或 Java 从 ".sql"文件构建 MSSQL 数据库?

java - 使用构造函数初始化静态字段是否总是被认为是不好的做法?

java - 对 List<Generic> 显式强制转换的怀疑

javascript - Javascript 可以获取文本形式的函数吗?

Java - MySQL | double 和小数点

java - 是否可以从 Java 中的对象构造函数中删除泛型类型参数?

java - 在 Spring 4.1 中注入(inject)泛型列表

c# - 旧版 API 需要将回调名称作为字符串传递。我可以通过扩展方法改进该 API 吗?