Перехват доступа к полям и методам Java, создание прокси-объектов - PullRequest
3 голосов
/ 06 июня 2011

Я хочу создать такой объект в Java, который будет содержать некоторую функцию диспетчера, такую ​​как Object getAttr(String name), которая будет получать все попытки доступа к атрибутам - поэтому, если я сделаю System.out.print(myObj.hello), фактический код будет преобразован во что-то вродеSystem.out.print(myObj.getAttr('hello')), и если я сделаю myObj.hello = 123, оно должно выполняться как myObj.setAttr('hello', 123).Пожалуйста, обратите внимание, что я должен иметь возможность использовать ЛЮБОЕ имя атрибута, я не знаю заранее списка возможных имен.

Так, в этом случае, возможно ли это когда-либо?

UPD # 1: Я пишу новый язык для JVM (как-то (J | P), похожий на ython, так что давайте назовем его Jython) с очень тесной интеграцией с Java.Одной из требуемых особенностей дизайна является возможность беспрепятственного доступа к атрибутам объектов Jython из кода Java, просто набрав jythonObject.some_attribute.Итак, вот сделка.

Закрыто: Использование AOP через AspectJ, кажется, единственно возможное решение для этого, поэтому спасибо всем за помощь, и особенно Томасу за самый расширенный ответ:)

Ответы [ 5 ]

3 голосов
/ 06 июня 2011

Использование чистой Java невозможно, кроме как через:

Манипуляция байт-кодом

Например, используя AspectJ.

Процессор аннотаций

Использование собственного процессора аннотаций, который также является манипуляцией с байт-кодом. Projekt Lombok делает что-то вроде этого.

Синтетический метод доступа

То есть, если код в любом случае использует синтетический метод доступа (в этом случае вы можете теоретически создать прокси):

public class Test {
    public static void main(String... args) {
        TestClass t = new TestClass();
        // this is actually calling a synthetic accessor method
        t.hello = "x";
    }
    static class TestClass {
        private String hello;
    }
}
2 голосов
/ 06 июня 2011

Если мы будем строго придерживаться ООП, ваши поля вообще не должны быть доступны извне. Доступ к полям должен осуществляться через методы get / set.

И методы перехвата интерфейса возможны через динамические прокси . (Важное примечание: вы не можете делать это с классами, только с интерфейсами.)

Если это не соответствует вашим потребностям (хотя, если вы не пишете сторонний инструмент, вероятно, оно должно), то есть только грязный способ, аспектно-ориентированное программирование или простой взлом байт-кода.

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

1 голос
/ 06 июня 2011

Вам придется использовать AspectJ (http://www.eclipse.org/aspectj/) или другую библиотеку AOP.

0 голосов
/ 27 февраля 2016

В языке Groovy есть инструменты для AOP, и крошечная библиотека уже существует для обработки вашего дела: https://github.com/nanonull/bean-trace

0 голосов
/ 06 июня 2011
...