2

これは非常に悪い OO ですが、コーダー自身以外の誰かが使用するコードにこれを入れようとしているわけではありません。コーダーによるテスト以外では決して呼び出すことはできません。

これが私が直面している問題です。外部で定義された一連のクラスがあります。それらを変更することはできません(もちろん、サブクラス化または呼び出しはできません)。これらにはさまざまな名前がありますが、スーパークラス (オブジェクトを除く) を拡張したり、インターフェイスを実装したりしません。ただし、それぞれについて私が知っていることは、「call」というメソッドがあるということです。

テストのために、これらのクラスの呼び出しメソッドのいずれかを呼び出すコードを作成しようとしています。しかし、もちろん、call はすべての Object に対して定義されているわけではないため、Object.call() とだけ言うことはできません。

基本的に、これは機能します:

MyClassOne classOne = new MyClassOne();
MyClassOneInput classOneInput = new MyclassOneInput();

classOne.call(classOneInput);

しかし、これはしません:

Object clazz = getClassFromElsewhere();
Object clazzInput = getClassInputFromElsewhere();

clazz.call(clazzInput).

明らかに、Java は厳密に型指定された言語です。

しかし、このシステムで作業しているすべての人のテストを 10 倍高速化するために、何らかの方法でそれを回避し、何らかの方法で「call」メソッドを任意のクラスと任意の ClassInput に使用できますか? 間違ったクラスが渡された場合に例外が発生したり、完全に壊れたりしても問題ありません。

オブジェクト指向に違反するのを手伝ってください。

4

3 に答える 3

8

これを行うには、リフレクションを使用できます。リフレクション 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)" を呼び出す必要があります。

于 2012-05-16T21:34:14.157 に答える
6

これはJava Reflectionの完璧な使い方です。これは疑似コードの例ですが、次のようになります

 Object obj = getExternalObject();
 Method meth = obj.getClass().getDeclaredMethod("call");
 meth.invoke(obj);
于 2012-05-16T21:33:05.203 に答える
3

反射を使用

  1. を使用してクラスを取得しますgetClass()
  2. を使用して「呼び出し」メソッドを見つけますgetMethod()
  3. 見つかった場合は、オブジェクトでそれを呼び出します

例えば

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) {

メソッド名が文字列として指定された場合、Java メソッドを呼び出すにはどうすればよいですか? を参照してください。

また、動的 JVM 言語 (JRuby、Jython、Groovy) を調べることも検討します。このようなことを行うと、「Bad OO」が少なくなり、より自然に感じる可能性があります。

于 2012-05-16T21:32:26.310 に答える