IllegalAccessException

IllegalAccessException

请考虑以下类(class)

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.NoSuchMethodExceptionConstructor.newInstance()的JavaDoc指出:

私有(private)构造函数符合我对“无法访问的构造函数”的期望。为什么此示例改为抛出NoSuchMethodException,并且在什么情况下可以抛出IllegalAccessException

最佳答案

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

另一方面,如果您使用IllegalAccessException,则newInstance方法将抛出getDeclaredConstructor,因为此特定方法从所有可用的构造函数中选择了构造函数,而不仅仅是公共(public)的构造函数,因此虽然无法访问,但仍将检索示例中的私有(private)构造函数。

下面将抛出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)

09-16 21:39