Nano Hash - криптовалюты, майнинг, программирование

Непоследовательное поведение с методом вызова отражения Java

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

А.java:

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

    }
}

Б.джава:

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

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

Метод «вызов» в main в C завершается с ошибкой:

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

Если метод «вызова» в C точно такой же, как переопределенный метод в p.B. Однако, если он раскомментирован, исключение не генерируется.

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

24.09.2019

  • В каком пакете находится класс А? В какой комплектации класс С? 24.09.2019

Ответы:


1

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

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

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

24.09.2019
  • Спасибо за ваш ответ. Вы правы насчет репликации с помощью вызова A.foo(), чтобы поведение было последовательным. Что мне не нравится, так это то, что invoke() вызывается для объекта класса C, а не для объекта класса B, он наследует только класс B. Поэтому он должен вести себя как один, разрешая вызов пакета private A. Другое мнения? 25.09.2019
  • это просто то, как работает полиморфизм, метод находится в классе B, поэтому не имеет значения, какой именно объект. Если бы простое расширение некоторого класса дало бы доступ ко всему в его пакете... тогда вся видимость была бы просто бесполезной. 26.09.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..