结合 Java 泛型和反射以避免强制转换
我有一些这样的代码:
Object doMethod(Method m, Object... args) throws Exception {
Object obj = m.getDeclaringClass().getConstructor().newInstance();
return m.invoke(obj, args);
}
我使用的代码有点复杂,但这就是它的想法。要调用 doMethod,我会执行以下操作:
Method m = MyClass.class.getMethod("myMethod", String.class);
String result = (String)doMethod(m, "Hello");
这对我来说效果很好(参数数量可变)。 令我烦恼的是调用者中必须强制转换为String
。因为myMethod
声明它返回一个String
>,我希望 doMethod
足够聪明,可以将其返回类型更改为 String
。有没有某种方法可以使用Java泛型来完成这样的事情?
String result = doMethod(m, "Hello");
int result2 = doMethod(m2, "other", "args");
I have some code like this:
Object doMethod(Method m, Object... args) throws Exception {
Object obj = m.getDeclaringClass().getConstructor().newInstance();
return m.invoke(obj, args);
}
The code I use is a little more complex, but that's the idea of it. To invoke doMethod
I do something like this:
Method m = MyClass.class.getMethod("myMethod", String.class);
String result = (String)doMethod(m, "Hello");
This works just fine for me (variable number of arguments and all). The thing that irks me is the necessary cast to String
in the caller. Since myMethod
declares that it returns a String
, I'd like doMethod
to be smart enough to change its return type to also be String
. Is there some way of using Java generics to accomplish something like this?
String result = doMethod(m, "Hello");
int result2 = doMethod(m2, "other", "args");
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当然,
人们对需要完成这样的事情的架构感到好奇,但这远远超出了范围:)
如果您不喜欢这样,您也可以放弃 returnType 的绑定,编译器将自动转换它无论您将返回类型分配给什么。例如,这是合法的:
演员将是您试图将其分配给的任何对象,但我认为大多数人会认为这是可疑的。
Sure,
One is idly curious about the architecture that calls for such a thing to be done, but that's well out of scope :)
If you don't like that you can also leave off the binding of returnType and the compiler will automatically cast it to whatever you're assigning the return type to. e.g., this is legal:
The cast will be to whatever you are attempting to assign it to, but I think most people would consider it suspect.
我希望该方法已被参数化以捕获返回类型。您总是可以通过用自己的 MethodEx 包装 Method 来自己做到这一点...这样做也可以让您提供一些非常漂亮的外观...
这只是一个起点 - 您可以在 MethodEx 上拥有工厂方法,它可以做很多事情预先验证以确保方法是公共的,等等。
最后,如果您正在缓存方法实例等并处理动态加载的类,这也是一个很好的机会来防御性地引入弱引用(对方法和返回type),因此您不必在代码中小心地固定整个类加载器。
I wish that Method had been parameterized to capture the return type. You could always do that yourself by wrapping Method with your own MethodEx... Doing so would allow you to provide some pretty nice facades too...
This is just a starting point -- you can have factory methods on MethodEx that does a lot of up-front validation to make sure method is public, etc.
Finally, if you are caching the Method instances etc and dealing with dynamically loaded classes, this would also be a good opportunity to defensively introduce weak references (to the method and the return type) so you don't have to be as careful about pegging entire classloaders throughout your code.
你可以尝试一下,
尽管它将演员阵容转移到例程本身。一般来说,您尝试做的事情听起来不像是好的做法。反射本身会产生一些性能开销,但这也许并不重要?
You could try
Although it moves the cast to the routine itself. In general what you're trying to do doesn't sound like good practice. Reflection itself incurs some performance overhead, but perhaps that not of concern?