我需要调用一个函数 - (属性的getter和setter),但我的问题是,属性的名称是在运行时生成的(某个变量的名称+数字)。
是否可以通过javassist或gclib操作字节码,以便将函数调用定向到某个代理对象/函数,并且有真实的方法名称和从被调用函数名称中提取的数字,以便我可以调用之后的功能(以数字作为参数)?
我尝试了以下内容,但它没有用:
MethodHandler handler = new MethodHandler() {
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) {
String realMethodName=thisMethod.substring(0,5);
Integer param=Integer.parseInt(thisMethod.substring(5));
Method m = self.getClass().getMethod(realMethodName);
m.invoke(self,param);
return null;
}
};
答案 0 :(得分:1)
我认为这可能是使用Java反射代理对象的少数情况之一可能派上用场。
你可以定义一些接口,但是将方法委托给(动态)调用处理程序,然后调用那些" getter / setter"方法
附注:在实现这样的调用处理程序时,您必须了解对相应对象的ANY方法调用将触发其调用"方法;调用toString或equals或从Object继承的其他任何事件时的事件。
编辑:还有一个(不同的)想法:你确定你需要创建动态方法名吗?如果您有一些数字(或基于字符串)键 - 例如没有使用Map?
像
Map<WhateverKeyType,YourPropertyClass>
这将是更多&#34;正常的Java&#34;处理问题的方法(而不是考虑反射或字节码操作)。
答案 1 :(得分:0)
如果你想实现类似的东西,但想到使用另一个库而不是javassist,请考虑using Byte Buddy(我写的,为了披露)。
考虑到,你有一个界面
interface Foo { Object getProperty() }
您希望实现访问bean的属性
class Bar { Object getAbc123() { ... } }
然后使用Byte Buddy,你可以实现一个类
Foo accessor = new ByteBuddy()
.subclass(Foo.class)
.method(named("getProperty"))
.intercept(MethodCall.invoke(Bar.class.getDeclaredMethod("getAbc123"))
.on(new Bar()))
.make()
.load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded()
.newInstance();
接口的将getProperty
的调用重定向到您选择的方法。通过一些自定义,您肯定可以创建更通用的解决方案。