Несовместимое поведение с Java-методом «invoke» отражения - PullRequest
1 голос
/ 24 сентября 2019

Пожалуйста, посмотрите эти примеры классов.

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]);
//  }
}

Метод 'invoke' в main в C завершается с ошибкой:

IllegalAccessException: класс pB не может получить доступ к члену класса A с модификаторами "public static"

Если вызывать ''Метод в C точно такой же, как и переопределенный метод в pB. Однако, если он не закомментирован, исключение не выдается.

Почему разница?

1 Ответ

1 голос
/ 24 сентября 2019

Класс A является частным пакетом.Поскольку A и C находятся в одном и том же (по умолчанию) пакете, это законный доступ для вызова A.foo() из любого кода в классе C, но не в классе B, который находится в другом пакете.

Если вы переопределите метод, A.foo() вызывается из того же пакета.Если вы не переопределите метод, A.foo() вызывается из кода в другом пакете, что является недопустимым доступом.

Подобное поведение можно повторить, просто добавив оператор A.foo() в соответствующий invoke() методы.Однако в этом случае вы получите ошибку компиляции вместо ошибки времени выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...