Java Getters:始终执行特定方法

时间:2009-07-15 20:33:09

标签: java java-me getter

有没有办法定义一个方法,每次调用get时都会调用它?

我有一个Object Contact,不想设置updateLastUsed();在我的会员约30个吸气剂。

10 个答案:

答案 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)

我会说代理对象来调用所需的方法。