Class API中getDeclaredConstructors和getConstructors有什么区别?

73
我注意到在Java Reflection API中有两种不同的方法来调用构造函数: getDeclaredConstructors / getConstructors方法。尽管Java文档略有不同(getDeclaredConstructors似乎意味着它返回所有构造函数,而不仅是公共构造函数),但并不清楚为什么API明确支持这两种不同的方法。
更重要的是,我想知道:如果我们动态地调用类,何时会出现一种方法优于另一种方法的情况?例如,访问私有构造函数的目的是什么?
4个回答

77

getDeclaredConstructors(当您需要所有构造函数时使用)

返回一个Constructor对象数组,该数组反映了由此Class对象表示的类声明的所有构造函数。这些构造函数可以是public、protected、default(包)访问和private构造函数。

getConstructors(当您只需要public构造函数时使用)

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

因此,查看它们的文档,我认为它们之间的区别在于getConstructors仅返回public构造函数,而getDeclaredConstructors则返回所有构造函数(publicprotected、default(package)access和private

因此,如果您只需要public构造函数,则使用getConstructors即可。否则,如果您需要所有构造函数(忽略构造函数的访问修饰符),则使用getDeclaredConstructors


9
通过使用constructor.setAccessible(true),您可以反射调用私有构造函数。 - MeBigFatGuy
1
虽然这个答案是正确的,但还有一个小细节。编译器会自动为任何没有明确定义任何构造函数的类提供默认的(无参数)公共构造函数。getConstructors不会返回此默认构造函数,但getDeclaredConstructors会返回它。 - neXus
嗨neXus,你确定吗?看起来很疯狂,getDeclaredConstructor返回一个未声明的构造函数。这可能只是“自动声明”的构造函数可见性的问题吗? - Marco Servetto
1
我现在的测试是:getDeclaredConstructor()getConstructor()都返回编译器创建的(默认)构造函数。所以我认为你的猜测可能是正确的,@MarcoServetto。 - Per Lundberg

6
getDeclaredXX() 方法存在的目的是以不同于类的制造者所设想的方式操作类。请注意,有一个 getDeclaredMethod() 方法可用于调用私有方法,而 getDeclaredField() 方法则可用于获取/设置私有字段。

我不完全确定“合法”的使用情况,但这些方法显然对于执行某些任务非常有用。此外,这一系列的方法仅返回在类中明确声明的内容,而不是因为超类而存在于类中的内容。

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


0
我使用getDeclaredConstructors来创建一个类的工厂,该类的构造函数是私有的,以避免我的系统的“用户”直接创建这些类而不使用工厂。我发现这种方法非常有用。

-1
方法'getDeclaredConstructors'只返回在类内部声明的构造函数。而方法'getConstructors'还返回从父类继承而来的构造函数,即使它们没有在类内部声明。
所以这取决于你要做什么。没有绝对正确的方法,这真的取决于你是否需要父类的构造函数。

8
这是错误的。getConstructors()方法与getMethods()方法的行为不相似。它们都只获取给定类的构造函数,忽略超类的构造函数。(它们的区别在于获取的构造函数的可见性。)这符合实例化一个类时必须使用其中一个构造函数的事实,你不能绕过它们并直接调用其超类的构造函数之一。您可以编写几个测试类来测试这个问题。(我已经这样做了。)请删除这个误导性的答案。 - Mike Nakis
8
Java 中构造函数不会被继承。 - Paŭlo Ebermann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接