Kotlin/Java 泛型:在实例化期间何时会出现 IllegalAccessException?



请考虑以下类

open class BaseClass
class MyClass private constructor(string: String): BaseClass()

还有一个创建实例的泛型函数:

inline fun <reified T : BaseClass, reified A : Any> create(arg: A): T = T::class.java.getConstructor(arg::class.java).newInstance(arg)

以下测试失败:

@Test(expected = IllegalAccessException::class)
fun `should throw an IllegalAccessException`() {
val test: MyClass = create("test")
}

因为实际上抛出了java.lang.NoSuchMethodException。JavaDoc forConstructor.newInstance()指出:

@exception 非法访问异常,如果这个 {@code 构造函数} 对象 正在实施 Java 语言访问控制和底层 构造函数不可访问。

私有构造函数符合我对"无法访问的构造函数"的期望。为什么这个例子会抛出一个NoSuchMethodException,在什么情况下它可以抛出一个IllegalAccessException

getConstructor方法将尝试仅从公共构造函数列表中选择构造函数,不考虑私有构造函数。由于它找不到公共匹配项,因此会抛出NoSuchMethodException

另一方面,如果您改用getDeclaredConstructorIllegalAccessException将由newInstance方法抛出,因为此特定方法从所有可用的构造函数(而不仅仅是公共构造函数(中选取构造函数,因此将检索示例中的私有构造函数,尽管无法访问。

下面会抛出IllegalAccessException

T::class.java.getDeclaredConstructor(arg::class.java).newInstance(arg)

如果出于某种原因,您想克服它,您可以使用以下内容:

val ct = T::class.java.getDeclaredConstructor(arg::class.java)
ct.trySetAccessible()
return ct.newInstance(arg)

最新更新