java - Java反射“调用”方法的行为不一致

标签 java reflection

请参阅这些示例类。

A.java:

// A is not public
class A
{
    public static void foo()
    {

    }
}


B.java:

package p;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class B
{
    public void invoke() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException
    {
        Class clazz = Class.forName("A");
        Method method = clazz.getDeclaredMethod("foo", new Class[0]);
        method.invoke(null, new Object[0]);
    }
}


C.java:

import java.lang.reflect.InvocationTargetException;

public class C extends p.B
{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException
    {
        C c = new C();
        c.invoke();
    }

//  @Override
//  public void invoke() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException
//  {
//      Class clazz = Class.forName("A");
//      Method method = clazz.getDeclaredMethod("foo", new Class[0]);
//      method.invoke(null, new Object[0]);
//  }
}


C语言中main中的“调用”方法失败,原因是:

IllegalAccessException:类p.B无法使用修饰符“ public static”访问类A的成员

如果C中的“调用”方法与p.B中的替代方法完全相同。但是,如果不加注释,则不会引发任何异常。

为什么会有所不同?

最佳答案

A是包专用的。由于AC在同一(默认)程序包中,因此可以合法地从类A.foo()中的任何代码调用C,但不能在其他类中的B中调用该代码。

如果覆盖该方法,则会从同一包中调用A.foo()。如果不重写该方法,则会从其他程序包中的代码中调用A.foo(),这是非法访问。

您可以通过在相应的A.foo()方法中添加语句invoke()来复制类似的行为。但是,在这种情况下,您将得到编译错误而不是运行时错误。

关于java - Java反射“调用”方法的行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58082798/

相关文章:

Java/Selenium 应用程序 - 如何获取被测应用程序的 session ID?

JavaFX 列/单元格值未更新

reflection - 如何获取 Kotlin 类(M12 中的 KClass)的声明函数?

java - 是否有使用编码/解码的替代方法?

java - SPARQL 选择特定数据

java - 可从所有 Servlet 访问数据

c# - 使用 Lambda 表达式获取方法名称

.net - 更改了 .Net 4 中泛型方法的 LdToken 行为?

c# - 跨序列化对象反射以设置 PropertyChanged 事件

java - 反射性地获取项目中的所有包?