我想在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集成。其中一个有用的设计功能是只需键入jythonObject.some_attribute
即可从Java代码无缝访问Jython对象属性。所以这是交易。
已关闭:通过AspectJ使用AOP似乎是唯一可行的解决方案,所以非常感谢大家的帮助,尤其是托马斯最广泛的答案:)
答案 0 :(得分: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;
}
}
答案 1 :(得分:2)
如果我们严格遵守OOP理由,您的田地根本不应该从外面进入。所有字段访问都应该通过get / set方法完成。
通过dynamic proxies可以拦截界面的方法。 (重要提示:您不能使用类,只能使用接口。)
如果这不符合您的需求(虽然除非您正在编写第三方工具,但它可能应该这样),那么只有乱码的方式,面向方面的编程或直接的字节码黑客攻击。
如果我们知道你需要做什么,这会有所帮助。
答案 2 :(得分:1)
您必须使用AspectJ(http://www.eclipse.org/aspectj/)或其他AOP库。
答案 3 :(得分:0)
答案 4 :(得分:0)
Groovy语言有AOP工具, 并且已存在用于处理案例的小型库:https://github.com/nanonull/bean-trace