【问题标题】:What is the difference between getDeclaredConstructors and getConstructors in the Class API?Class API 中的 getDeclaredConstructors 和 getConstructors 有什么区别?
【发布时间】:2012-01-05 03:46:30
【问题描述】:

我注意到在 Java 反射 API 中有两种不同的方法来调用构造函数:getDeclaredConstructors/getConstructors 方法。尽管 Java 文档略有不同(getDeclaredConstructors 似乎暗示它返回所有构造函数,而不是公共构造函数),但不清楚为什么 API 明确支持这两种不同的方法。

更重要的是,我想知道:如果我们动态调用类,什么时候一种方法比另一种更可取?比如访问私有构造函数的目的是什么?

【问题讨论】:

    标签: java reflection constructor


    【解决方案1】:

    “getDeclaredConstructors”方法仅返回在类中声明的构造函数。方法“getConstructors”还返回未在类中声明但从超类继承的构造函数。

    所以这取决于你要做什么。没有正确的方法,这真的取决于你是否还需要超级构造函数。

    【讨论】:

    • 这是错误的。 getConstructors() 方法_not_ 的行为类似于 getMethods() 方法。它们都只获取给定类的构造函数,忽略超类的构造函数。 (它们的区别在于它们获取的构造函数的可见性。)这是因为实例化一个类时必须使用其构造函数之一,您不能绕过它们并直接调用其超类的构造函数之一。您可以编写几个测试类来测试它。 (我做到了。)请删除这个误导性的答案。
    • 构造函数在 Java 中不被继承。
    【解决方案2】:

    getDeclaredXX() 方法的存在是为了以这些类的创建者不一定想要的方式来操作类。请注意,getDeclaredMethod() 方法允许您调用私有方法,getDeclaredField() 方法允许您获取/设置私有字段。

    我不完全确定“合法”用例,但这些显然对做某些事情很有用。此外,这一系列方法只返回在类中明确声明的东西,而不是由于超类而存在于类中的东西。

    我想,出于同样的原因,访问私有构造函数可能很有用。

    【讨论】:

      【解决方案3】:

      getDeclaredConstructors(当你想要所有构造函数时)

      返回一个 Constructor 对象数组,反映由该 Class 对象表示的类声明的所有构造函数。这些是公共的、受保护的、默认(包)访问和私有构造函数。

      getConstructors(当你想要只有public 构造函数时)

      返回一个包含 Constructor 对象的数组,该数组反映了此 Class 对象表示的类的所有公共构造函数。

      因此,查看它们的文档,我认为区别在于 getConstructors 仅返回 public 构造函数,而 getDeclaredConstructors 返回所有构造函数(publicprotected,默认(包)访问,和private)

      因此,如果您只需要 public 构造函数,然后使用 getConstructors,这很容易。否则,如果您需要所有构造函数(忽略构造函数的访问修饰符),请使用getDeclaredConstructors

      【讨论】:

      • 并且通过使用constructor.setAccessible(true),你可以反射性地调用私有的构造函数。
      • 虽然这个答案是正确的,但有一点需要注意。编译器会自动为任何未显式定义任何构造函数的类提供默认(无参数)公共构造函数。 getConstructors 不会返回此默认构造函数,但 getDeclaredConstructors 会。
      • 嗨 neXus,你确定吗? getDeclaredConstructor 返回一个 NOT DECLARED 的构造函数看起来很疯狂。这是否可能只是“自动声明”构造函数的可见性问题?
      • 我现在的测试:getDeclaredConstructor()getConstructor() 都返回编译器创建的(默认)构造函数。所以我认为你的猜测可能是正确的@MarcoServetto。
      【解决方案4】:

      我使用getDeclaredConstructors 创建一个类工厂,其构造函数是私有的,以避免我系统的“用户”可以直接创建这些类而不使用工厂。我觉得这个方法很有用。

      【讨论】:

        猜你喜欢
        • 2020-12-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-07
        • 1970-01-01
        • 2013-02-15
        • 1970-01-01
        • 1970-01-01
        • 2011-05-17
        相关资源
        最近更新 更多