Получение доступа уровня поля к полю извне пакета? - PullRequest
2 голосов
/ 12 ноября 2009

Я использую API, в котором есть абстрактный класс, который я хочу расширить (в своем конкретном классе), чтобы использовать некоторые методы в родительском. К сожалению, программист этого класса API решил, в частности, с одним полем предоставить ему доступ на уровне пакета без открытого установщика. Вместо этого значение поля устанавливается в методе. Существует ли общий «шаблон моста», чтобы я мог получить / установить это поле соответствующим образом? Это важно не только для моей функциональности, но и для тестирования (поскольку мне нужно будет смоделировать значение, установленное в этом поле в моем тесте). Спасибо!

Ответы [ 4 ]

4 голосов
/ 12 ноября 2009

Некоторые возможности:

  • Получите и измените исходный код «API».

  • Напишите класс в том же пакете, чтобы получить доступ к нужному полю и открыть его.

  • Напишите обертку вокруг класса API, обеспечивающую доступ к этому полю с любой измененной семантикой, которая вам нравится.

  • Используйте отражение, чтобы сломать защиту доступа для класса API.

1 голос
/ 12 ноября 2009

Вам нужно будет использовать отражение, чтобы установить поле. Для того, чтобы установить поле, вы должны вызвать setAccessible на нем. Я не проверял это, но что-то вроде следующего должно работать:

ClassWithProtectedField o = new ClassWithProtectedField();
Class c = o.getClass();
java.lang.reflect.Field protectedField = c.getField("protectedField");
protectedField.setAccessible(true);
protectedField.set(o, someValue);

http://java.sun.com/j2se/1.5.0/docs/api/java/lang/reflect/Field.html

0 голосов
/ 12 ноября 2009

Если вы можете, вы можете создать подкласс класса API в исходном пакете и открыть поле для всех. Если вы не можете сделать это, вы можете использовать отражение для изменения значения поля, предполагая, что ваш SecurityManager настроен на его разрешение, но это похоже на запах кода.

0 голосов
/ 12 ноября 2009

Если вы контролируете SecurityManager или его нет, вы можете использовать Reflection, чтобы сделать поле доступным, а затем изменить его значение.

Пример кода:

import java.lang.reflect.Field;

public class ModifyProtectedFieldSample {

    public static void setProtectedField(final Object targetClass,
                                     final String fieldName,
                                     final Object value) {
    try {
        final Field field = targetClass.getClass().getDeclaredField(fieldName);
        if (!field.isAccessible()) {
            field.setAccessible(true);
        }

        field.set(targetClass, value);
    } catch (NoSuchFieldException e) {
        System.out.println("NoSuchFieldException " + e);
    } catch (SecurityException e) {
        System.out.println("SecurityException"+ e);
    } catch (IllegalAccessException e) {
        System.out.println("IllegalAccessException"+ e);
    }
  }

  public static void main(final String[] args) {
    setProtectedField(String.class, "someFieldName", Boolean.FALSE);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...