Я работаю над модулем Java, который использует Groovy как зависимость времени компиляции, и я хотел бы добавить метод к моему классу Java Person
(как Groovy JDK) без написания кода Groovy.Добавление методов в класс с использованием Groovy в Java
В Groovy я бы добиться этого, как этот
Person.meta.doSomething = { String param -> println "do something: ${param}" }
Как я могу сделать это с помощью Groovy формы API Java?
EDIT 1:
я реализовал следующие до сих пор, и я почти там. Я создаю экземпляр класса Expando для Person
и зарегистрирую MethodClosure
, который делегирует вызов метода методу в классе PersonDefaultMethods
.
ExpandoMetaClass expando = new ExpandoMetaClass (Person.class, true, false);
expando.registerInstanceMethod ("format", new MethodClosure (new PersonDefaultMethods(), "format"));
expando.initialize();
PersonDefaultMethods
содержит реализацию методов я заявленных в классе Expando.
public class PersonDefaultMethods {
public String format(String format) {
return this.toString(); // this one gets called
}
public String format(Person self, String format) { // but I want this method to be called
return self.getFirstname() + " " + self.getLastname();
}
}
Когда я знаю, что выполнить Groovy скрипт в этом контексте я в состоянии вызвать метод format
на Person
инстанции, но я не могу получить доступ к delegate
, как я обычно можно с помощью замыкания.
EDIT 2:
Подход с использованием закрывающий подкласса или анонимный класс закрытия терпит неудачу в моей реализации.
ExpandoMetaClass expando = new ExpandoMetaClass(Person.class, true, false);
expando.registerInstanceMethod("format", new Closure(this) {
@Override
public Object call(Object arguments) {
return super.call(arguments);
}
@Override
public Class[] getParameterTypes() {
return new Class[] { String.class};
}
});
expando.initialize();
Это делает свою работу. Спасибо.
Даже если вы можете заставить это работать, разве ваш код не станет бесполезным для поиска и вызовов реестра? Java не подходит для такого расширения экземпляра. Отсюда Groovy –
Я абсолютно с тобой согласен. Единственная причина, по которой я пытаюсь использовать этот подход, заключается в том, что моя компания использует Eclipse (без поддержки Groovy), и если я начну класть классы Groovy в свое рабочее пространство, проект больше не будет построен ... Я знаю, что это плохо но я не могу его изменить (пока). – saw303
re: «невозможно получить доступ к делегату».В MethodClosure делегат/владелец используется для вызова метода, здесь PersonDefaultMethods, поэтому он не будет работать так. Вам понадобится подкласс Closure. – blackdrag