有没有办法定义一个方法,每次调用get时都会调用它?
我有一个Object Contact,不想设置updateLastUsed();在我的会员约30个吸气剂。
答案 0 :(得分:3)
您可以创建一个将属性名称作为输入的通用getter,而不是访问属性的getter。如果您的属性属于不同类型,则返回类型需要为Object。
在这个通用的getter中,你可以调用属性getter和updateLastUsed()方法。为了安全起见,所有财产都是私人的。
答案 1 :(得分:2)
你可以添加对每个方法的调用(无聊),或者使用某种形式的AOP(例如下面的AspectJ,例如)来匹配类型的getter并调用updateLastUsed()方法。
编辑:有几个人指出30个吸气剂是一种代码气味,并且调用另一种方法是副作用。第一个陈述是一个公平的指标,但不是一个规则。这种类型可能有很多原因,如果没有进一步的信息,我会将其作为建议来检查你是否可以将责任分成两种或更多种类型。
关于副作用的另一点可能相关也可能不相关。有许多横切关注的问题,它适用于吸气剂方法。例如,日志记录,身份验证和缓存。示例方法updateLastUsed()可能是缓存策略的一部分,因此我认为对该问题的无条件批评是不合理的。
如何在AspectJ中实现切入点和建议的示例如下:
package test;
public aspect TestAspect {
/**
* Match all getters of test.Contact and bind the target.
*/
protected pointcut contactGetters(Contact contact) :
execution(* test.Contact.get*()) && target(contact);
/**
* Before execution of each getter, invoke the updateLastUsed() method
* of the bound target.
*/
before(Contact contact): contactGetters(contact) {
contact.updateLastUsed();
}
}
答案 2 :(得分:2)
我会建议AOP但是如果它是J2ME我们谈论你最好在你的30个访问者的每一个中手动插入“onGetCalled()”然后在该方法中编码你需要的任何东西。您可能希望传递被调用方法的名称(或访问的属性),以备将来需要时使用。
答案 3 :(得分:1)
这看起来像是面向方面编程(AOP)的工作。
为以get*
“新”AspectJ 5的东西支持使用注释来定义方面切入点,这样你就可以注释你的getter调用一个切入点@Before
来执行方法的主体。
答案 4 :(得分:1)
这样做需要像AOP这样的东西。除了this之外,我不知道J2ME对支持的支持程度如何。
答案 5 :(得分:1)
除了AOP,你可以使用java.lang.reflect.Proxy
或字节码操作......
但不是在J2ME上
我建议调用updateLastUsed()30次。
答案 6 :(得分:1)
这是一种方式。它不漂亮,但你可能更喜欢重复:
public class GetterTest extends TestCase {
private static class Thing {
public int accessCount;
private String name;
private int age;
private <T> T get(T t) {
accessCount++;
return t;
}
public String getName() {
return get(name);
}
public int getAge() {
return get(age);
}
}
public void testGetIncrementsAccessCount() throws Exception {
Thing t = new Thing();
assertEquals(0, t.accessCount);
t.getName();
assertEquals(1, t.accessCount);
t.getAge();
assertEquals(2, t.accessCount);
}
}
显然,我的get()只是递增accessCount,你会想要一些其他的行为,但这个想法就在那里。
答案 7 :(得分:1)
使用正则表达式将方法调用附加到getter标头。
查找
\w+ get\w+\s*\(\)\s*\{(\s*)
替换为:
\0updateLastUsed();\1
使用Eclipse 3.5(Galileo)在“查找/替换”对话框中使用“全部替换”测试了这些表达式。
请注意,您使用的编辑器必须支持多行匹配(或者您必须启用它)。对于EmEditor 8.05,我必须将搜索字符串修改为:
\w+ get\w+\s*\(\)\s*\{\s*(\n\s*)
以便明确匹配新行。替换字符串保持不变。
答案 8 :(得分:1)
你可以做一些奇特的事,但老实说这就是为什么宏被添加到编辑器中,这样你就可以快速重复无聊的代码。
我只是让所有getter调用该方法,然后使用宏来创建调用(如果它需要通过方法不同)。这一切只需要做一次,然后你就忘了它......
答案 9 :(得分:0)
我会说代理对象来调用所需的方法。