gpt4 book ai didi

java - 为什么使用反射访问外部类的私有(private)成员会抛出 IllegalAccessException?

转载 作者:搜寻专家 更新时间:2023-11-01 03:18:46 25 4
gpt4 key购买 nike

给出下面的代码示例,为什么 accessUsingReflection -> theAnswer.get( outer ) 抛出 IllegalAccessExceptionaccessDirectly 打印 42 就好了吗?

Exception in thread "main" java.lang.IllegalAccessException: Class Outer$Inner can not access a member of class Outer with modifiers "private"

根据 this SO answer ,我希望它能正常工作,因为访问确实发生了“(...) 来自允许访问它的类”。

import java.lang.reflect.Field;

public class Outer
{
private int theAnswer = 42;

public static class Inner
{
public void accessDirectly( Outer outer )
{
System.out.println( outer.theAnswer );
}

public void accessUsingReflection( Outer outer ) throws NoSuchFieldException,
SecurityException,
IllegalArgumentException,
IllegalAccessException
{
Field theAnswer = Outer.class.getDeclaredField( "theAnswer" );
// Of course, uncommenting the next line will make the access using reflection work.
// field.setAccessible( true );
System.out.println( theAnswer.get( outer ) );
}
}

public static void main( String[] args ) throws NoSuchFieldException,
SecurityException,
IllegalArgumentException,
IllegalAccessException
{
Outer outer = new Outer();
Inner inner = new Inner();
inner.accessDirectly( outer );
inner.accessUsingReflection( outer );
}
}

最佳答案

像这样的“为什么”问题很难回答 - 有很多层次的“为什么”,包括为什么设计师选择这样做? 规范的哪一部分允许这样做? 底层技术细节是什么?

我会回答最后一个问题,但我不确定这是否是您想要的。

Java 运行时(JVM、安全模型等)在很大程度上不了解内部类。它们在很大程度上是语言问题。

其中一个后果是编译器使用一些隐藏的技巧来允许内部/外部类访问彼此的私有(private)成员,即使运行时通常不允许这样做。

其中一个技巧是您的 accessDirectly 方法实际上并未直接访问该字段。编译器在外部类上添加了一个隐藏方法,该方法返回 theAnswer 的值。

字段 (theAnswer) 仍然是私有(private)的,就运行时安全模型而言,不能在拥有(外部)类之外访问。

因此,有些事情您可以(表面上)在 Java 代码中做而您不能使用反射来做,因为它们依赖于编译器中的特殊行为,这些行为不会在反射库中复制。

您可以阅读更多here

关于java - 为什么使用反射访问外部类的私有(private)成员会抛出 IllegalAccessException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38070905/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com