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

#java #oop #reflection #method-invocation #class-visibility

#java #ооп #отражение #метод-вызов #класс-видимость

Вопрос:

Этот вопрос касается механизмов отражения языка программирования Java.

У меня есть интерфейс:

 package A;

public interface MyInterface {

    public boolean doSomething(Object... parameters);
}
  

У меня есть несколько классов реализации для этого интерфейса. Вот несколько примеров:

 package B;
import A.*;

abstract class BaseImplementation implements MyInterface {

    private Object field;

    protected BaseImplementation() {

        super();
    }

    public void setField(Object aField) {

        field = aField;
    }

    public Object getField() {

        return field;
    }
}
  

 package B;
import A.*;

public class ConcreteImplementation extends BaseImplementation {

    public ConcreteImplementation() {

        super();
    }

    ...

    // The concrete implementation provides an implementation for all
    // inherited abstract methods. Apart from this no other methods
    // are overridden.
    // This concrete class provides accessor methods for all of its own
    // private fields.

    ...
}
  

(отредактировано) В качестве примечания (это может не иметь отношения к проблеме, касающейся механизма отражения):

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

Для правильной работы разных реализаций интерфейса требуются разные ресурсы / объекты. Чтобы уменьшить дублирование кода, я использую абстрактные родительские классы. Эти абстрактные классы не используются вне своих пакетов.

При создании экземпляра и инициализации экземпляра конкретного класса реализации я прибегаю к механизмам отражения. Для этой цели у меня есть служебный класс (который находится в отдельном пакете), где я должен указать желаемое classname, какое поле получает какое значение (т. Е. Затем будут найдены соответствующие методы установки) и порядок, в котором вызываются методы установки.

У меня две разные среды разработки, и в каждой установлена другая версия java (1.5.x и 1.6.x). Это в основном используется для перекрестной проверки поведения реализации.

Создание экземпляра конкретного класса реализации работает в обеих средах. Но в более старой версии Java инициализация завершается неудачей. Каким-то образом невозможно получить доступ к общедоступному методу установки базового класса (базовый класс имеет видимость по умолчанию). В более новой версии Java нет проблем с доступом к методу setter.

Один из найденных мной обходных путей — изменить видимость базового класса (по умолчанию -> общедоступный). Вопрос в том, есть ли способ сохранить видимость (по умолчанию) и по-прежнему вызывать метод setter с механизмами отражения?

Комментарии:

1. Предоставление интерфейса (или абстрактного класса) с ограниченной видимостью звучит немного странно. Немного похоже на рисование карты невидимыми чернилами.

Ответ №1:

В зависимости от установленных вами ограничений безопасности вы можете использовать

 AccessibleObject.setAccessible(boolean);
  

(AccessibleObject — это интерфейс, реализованный полем, методом, конструктором). Перед вызовом reflections просто вызовите method.setAccessible(true); для объекта reflections, и если SecurityManager не выдает исключение, все должно быть в порядке.