Как я прерываю вызов метода со стандартными функциями Java (никакой AspectJ и т.д.)?

Нет гарантии, что ресурсы будут закрыты до тех пор, пока работает JVM, ваша предлагаемая реализация довольно опасна.

Что я хотел бы предложить. Сделайте класс A закрытым и используйте tryResourceClose-Statement Java. Пример здесь. https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

После выхода из блока try вы получаете возможность закрыть свои ресурсы.

Сам поток обычно не знает, открыта ли она или нет. Тем не менее, ваш собственный класс A может отслеживать, что потоки были закрыты или нет.

19
задан Tobias Hilka 23 February 2009 в 08:43
поделиться

6 ответов

Как Вы отмечаете, Вы не можете использовать JDK динамические прокси (никакой интерфейс), но использование Spring и CGLIB (JAR, включенный с Spring), можно сделать следующее:

public class Foo
{
    public void setBar()
    {
        throw new UnsupportedOperationException("should not go here");
    }

    public void redirected()
    {
        System.out.println("Yiha");
    }
}

Foo foo = new Foo();
ProxyFactory pf = new ProxyFactory(foo);

pf.addAdvice(new MethodInterceptor()
{
    public Object invoke(MethodInvocation mi) throws Throwable
    {
        if (mi.getMethod().getName().startsWith("set"))
        {
            Method redirect = mi.getThis().getClass().getMethod("redirected");
            redirect.invoke(mi.getThis());
        }
        return null;
    }
});

Foo proxy = (Foo) pf.getProxy();
proxy.setBar(); // prints "Yiha"
27
ответ дан 30 November 2019 в 02:52
поделиться

Если Вы готовы сделать что-то действительно ужасное, взглянуть на:

http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/

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

14
ответ дан 30 November 2019 в 02:52
поделиться

Java не имеет никаких фактических функций языка перехвата метода (не уверенный, что любой статический язык делает)

, мне отчасти нравится идея Nick's использовать интерфейс отладчика, это является просто средним.

я думаю короткий ответ, в котором Вы нуждаетесь: Нет нет способа прервать вызов метода в Java, на самом деле не заменяя класс с помощью прокси или обертки.

Примечание: библиотеки AOP просто заставляют это произойти автоматически.

2
ответ дан 30 November 2019 в 02:52
поделиться

Некоторые гуру Java могли бы осудить это, но я имел некоторый хороший успех с предотвращением типов примитивов и методов set в целом. Мой класс похож на это:

class Employee extends SmartPojo {
    public SmartString name;
    public SmartInt age;
}

Вы заметите две вещи: 1. все общедоступно. 2. Никакой конструктор.

волшебство происходит в SmartPojo, который ищет любое поле, которое реализует интерфейс "Smart" и инициализирует его. Так как это не примитив (и никакой заключительный класс), я могу добавить набор () и получить () методы для всех полей где угодно в моей модели в единственном месте . Таким образом, никакой метод set/метод считывания больше не пропадает впустую, потрясающе просто добавить уведомление (также в единственном месте), и т.д.

Правда, это больше не POJO, и это не Боб большинством способов, но я нашел, что эти старые идеи ограничивают меня больше, чем они помогают. YMMV.

1
ответ дан 30 November 2019 в 02:52
поделиться

Нет большого волшебства в AspectJ. Можно записать собственный агент. http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html , кажется, хорошая начальная точка.

0
ответ дан 30 November 2019 в 02:52
поделиться
  1. , Почему Ваш класс не может реализовать интерфейс? Вы могли просто извлечь некоторый интерфейс из него содержащий все методы, что Вы хотите прервать и использовать динамический механизм прокси легко. Это - также хорошая практика программирования для кодирования с интерфейсами и не классами.

  2. Вы могли использовать платформу Spring с Spring возможности AOP (которые используют динамические прокси внутри) сделать это. Необходимо будет просто определить класс как боб Spring в конфигурационном файле, и клиенты класса должны будут или получить его экземпляр от контекста приложения Spring или как зависимость автоматически (путем определения setMyClass (мГц MyClass) метод, например). Оттуда можно легко перейти к определению аспекта, который прерывает все вызовы метода этого класса.

0
ответ дан 30 November 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: