Рубрики
Без рубрики

Вызов частного метода на Java

Автор оригинала: baeldung.

1. Обзор

В то время как методы частные в Java, чтобы предотвратить их вызов из-за пределов класса владение, мы, возможно, все еще придется вызвать их по некоторым причинам.

Для этого нам необходимо обойти элементы управления доступом Java. Это может помочь нам добраться до угла библиотеки или позволить нам протестировать код, который обычно должен оставаться закрытым.

В этом коротком учебнике мы посмотрим, как мы можем проверить функциональность метода, независимо от его видимости. Рассмотрим два разных подхода: API Отражения Java и Spring’s ReflectionTestUtils.

2. Видимость вне нашего контроля

Для нашего примера давайте использовать утилиту класса ЛонгАррайУтил который работает на долго Массивы. Наш класс имеет два indexOf методика:

public static int indexOf(long[] array, long target) {
    return indexOf(array, target, 0, array.length);
}

private static int indexOf(long[] array, long target, int start, int end) {
    for (int i = start; i < end; i++) {
        if (array[i] == target) {
            return i;
        }
    }
    return -1;
}

Допустим, видимость этих методов не может быть изменена, и все же мы хотим назвать частную indexOf метод.

3. Java Отражение API

3.1. Поиск метода с отражением

В то время как компилятор не позволяет нам вызывать функцию, которая не видна нашему классу, мы можем вызывать функции через отражение. Во-первых, мы должны получить доступ к Метод объект, описывая функцию, которую мы хотим назвать:

Method indexOfMethod = LongArrayUtil.class.getDeclaredMethod(
  "indexOf", long[].class, long.class, int.class, int.class);

Мы должны использовать getDeclaredMethod для доступа к не частным методам. Мы называем это по типу, который имеет функцию, в данном случае, ЛонгАррайУтил , и мы проходим в типах параметров, чтобы определить правильный метод.

Функция может выйти из строя и сделать исключение, если метода не существует.

3.2. Разрешить доступ к методу

Теперь нам нужно временно повысить видимость метода:

indexOfMethod.setAccessible(true);

Это изменение будет продолжаться до тех пор, пока JVM не остановится, или доступные свойство возвращается к ложный.

3.3. Вызов метода с отражением

Наконец, мы называем вызов на объекте Метода:

int value = (int) indexOfMethod.invoke(
  LongArrayUtil.class, someLongArray, 2L, 0, someLongArray.length);

Теперь мы успешно получили доступ к частному методу.

Первый аргумент в вызвать является целевым объектом, а остальные аргументы должны соответствовать подписи нашего метода. Как и в данном случае, наш метод статические , и целевым объектом является родительский класс – ЛонгАррайУтил . Для вызова методов экземпляра мы передавайте объект, метод которого мы называем.

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

4. Весенний рефлексТестУтилы

Достижение внутренних классов является общей проблемой в тестировании. Тестовая библиотека Spring предоставляет несколько ярлыков, которые помогут унитарным тестам достичь классов. Это часто решает проблемы, характерные для унитарных тестов, где тест должен получить доступ к частному полю, которое Spring может мгновенно использовать во время выполнения.

Во-первых, мы должны добавить весенне-тестовый зависимости в нашем pom.xml:


    org.springframework
    spring-test
    5.3.4
    test

Теперь мы можем использовать вызватьМетход функции в ОтражениеТестУтилы , который использует тот же алгоритм, как выше, и экономит нам писать столько кода:

int value = ReflectionTestUtils.invokeMethod(
  LongArrayUtil.class, "indexOf", someLongArray, 1L, 1, someLongArray.length);

Поскольку это тестовая библиотека, мы не ожидаем использовать ее за пределами тестового кода.

5. Соображения

Использование отражения для обхода видимости функции имеет некоторые риски и может быть даже невозможно. Мы должны рассмотреть:

  • Позволит ли менеджер безопасности Java это в нашем времени выполнения
  • Будет ли функция, которую мы вызываем, без проверки времени компиляции, будет продолжать существовать для нас, чтобы позвонить в будущем
  • Рефакторинг нашего собственного кода, чтобы сделать вещи более заметными и доступными

6. Заключение

В этой статье мы рассмотрели, как получить доступ к частным методам с помощью API Java Reflection и использовать данные ОтражениеТестУтилы .

Как всегда, пример кода для этой статьи можно найти более на GitHub .