3

我想在 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 集成。想要的设计特性之一是能够通过键入从 Java 代码无缝访问 Jython 对象属性jythonObject.some_attribute。所以这里是交易。

已关闭:通过 AspectJ 使用 AOP 似乎是唯一可能的解决方案,因此感谢大家的帮助,尤其是 Thomas 提供了最广泛的答案:)

4

5 回答 5

3

使用纯 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;
    }
}
于 2011-06-06T15:43:14.540 回答
2

如果我们严格遵守 OOP 原则,那么您的字段根本不应该从外部访问。所有字段访问都应通过 get/set 方法完成。

并且可以通过动态代理拦截接口的方法。(重要提示:您不能使用类,只能使用接口。)

如果这不适合您的需求(尽管除非您正在编写第三方工具,它可能应该)那么只有混乱的方式,面向方面的编程或直接的字节码黑客。

如果我们知道您需要这样做,那将会有所帮助。

于 2011-06-06T15:49:53.260 回答
1

您必须使用 AspectJ (http://www.eclipse.org/aspectj/) 或其他 AOP 库。

于 2011-06-06T15:31:45.380 回答
0

查看面向方面的编程 (AOP)

于 2011-06-06T15:31:18.503 回答
0

Groovy 语言具有用于 AOP 的工具,并且已经存在用于处理您的案例的微型库:https ://github.com/nanonull/bean-trace

于 2016-02-27T19:35:35.593 回答