我在想,如果我有以下情况怎么办?
public class MyObject<T> {
private T myTObject;
public void setMyTObject(T m) {
myTObject = m;
}
public T getMyTObject() {
return myTObject;
}
}
现在我希望那个班级做出类似的反应:
MyObject<ObjectA> objA = new MyObject<ObjectA>();
ObjectA objAInstance = objA.getObjectA();
或
objA.setObjectA(otherObjectAInstance);
有没有办法根据T类名称动态创建方法? 或者我应该更好地将ObjectA扩展为MyObject并使用super.get / seMyObject()创建这些方法?
澄清:
我们的想法是动态生成getter和setter方法 所以,如果我创建一个实例:
MyObject<A> objA = new MyObject<A>();
我可以调用方法:
objA.getA();
getA()将在内部调用getMyTObject()或只返回myTObject
所以MyObject可能会根据T类做出反应并生成相应的方法。
我更新了成员属性以区别于MyObject类,这可能会导致混淆。还修复了方法返回和参数类型。
答案 0 :(得分:0)
更新答案已完全更改。
听起来你想通过反思来使用某些东西。真正动态生成方法名称的问题在于,正如其他人所评论的那样,它必须在字节码中完成,这意味着尝试使用动态类的其他类没有Java代码可以引用。 可以完成,但这将是一团糟。
相反,这是使用泛型的可能解决方案。请注意,这是一个快速和肮脏的黑客;我留给你来改进它。您可以使用所需的getter和setter定义一个接口,无论您希望它们命名为什么:
package com.example.dcsohl;
public interface IntegerWrapper {
public Integer getInteger();
public void setInteger(Integer i);
}
然后,要使用它们,你可以使用这个类来完成繁重的工作。请注意,错误检查不是很好;例如,它没有检查&#34; getFoo&#34; at all对应于传入的类的名称;也没有证实&#34; foo&#34; in&#34; getFoo&#34;匹配&#34; setFoo&#34;方法。这是你可以改进的。
package com.example.dcsohl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyWrapper<T> implements InvocationHandler {
Class<T> clazz = null;
T myvalue = null;
public static <W,T> W getInstance(Class<W> clazz, Class<T> clazz2) {
ProxyWrapper<T> wrapper = new ProxyWrapper<T>();
wrapper.setClass(clazz2);
@SuppressWarnings("unchecked")
W proxy = (W)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] {clazz}, wrapper);
return proxy;
}
private void setClass(Class<T> clazz) {
this.clazz = clazz;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// getter has no arguments
if (method.getName().startsWith("get") && (args == null || args.length == 0)) {
return myvalue;
} else if (method.getName().startsWith("set") && args.length == 1) {
Object o = args[0];
if (o.getClass().isAssignableFrom(clazz)) {
@SuppressWarnings("unchecked")
T val = (T)o;
myvalue = val;
return null;
}
} else {
throw new Exception();
}
return null;
}
}
最后,要使用它,这里有一个快速示例:
package com.example.dcsohl;
public class Main {
public static void main(String[] args) {
Integer foo = 5;
IntegerWrapper wrapper = ProxyWrapper.getInstance(IntegerWrapper.class, Integer.class);
wrapper.setInteger(foo);
Integer bar = wrapper.getInteger();
System.out.println(bar);
}
}
似乎很多工作只是为了避免编写简单的包装类,而且你是对的,但反射有其用途,这是一个采样器。