这是非常糟糕的OO,但我并不是想把它放在除编码员自己以外的任何人都可以使用的任何代码之外 - 除了编码员的测试外,它永远不会被调用。
这是我面临的问题:我有一系列外部定义的类。我无法以任何方式修改它们(当然我可以继承或调用它们)。它们有多种名称,但它们不扩展任何超类(Object除外),或实现任何接口。然而,我对它们的了解是,它们有一种称为“呼叫”的方法。
为了测试,我正在尝试编写将调用这些类的调用方法中的任何一个的代码。但是,当然,我不能只说Object.call()因为没有为每个Object定义调用。
基本上,这将起作用:
MyClassOne classOne = new MyClassOne();
MyClassOneInput classOneInput = new MyclassOneInput();
classOne.call(classOneInput);
但这不会:
Object clazz = getClassFromElsewhere();
Object clazzInput = getClassInputFromElsewhere();
clazz.call(clazzInput).
显然,因为Java是一种强类型语言。
但是,为了让每个在这个系统上工作的人快10倍的测试,我可以以某种方式解决这个问题并以某种方式对任何Class和任何ClassInput使用'call'方法吗?如果它生成了异常,或者如果传递了错误的类,那么我没有问题。
请帮我违反面向对象。
答案 0 :(得分:8)
您可以使用反射来执行此操作。 查看reflection API
这是一个简单的例子:
MyClassOne classOne = new MyClassOne();
MyClassOneInput classOneInput = new MyClassOneInput();
Method m = classOne.getClass().getMethod("call", MyClassOneInput.class);
m.invoke(classOne, classOneInput);
注意:您可以使用getDeclaredMethod
获取任何方法,包括私有和受保护的方法,但如果它们是私有/受保护的,则需要在它们上面调用“m.setAccessible(true)”。
答案 1 :(得分:6)
这是Java Reflection的完美用法。这是一个伪代码示例,但它看起来像这样
Object obj = getExternalObject();
Method meth = obj.getClass().getDeclaredMethod("call");
meth.invoke(obj);
答案 2 :(得分:3)
getClass()
getMethod()
e.g。
java.lang.reflect.Method method;
try {
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
然后
try {
method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
请参阅How do I invoke a Java method when given the method name as a string?
我还会考虑研究动态JVM语言(JRuby,Jython,Groovy),其中做这样的事情可能看起来不那么“坏OO”并且感觉更自然