3

オブジェクトがどのクラスに属しているかを知らなくても、そのメソッドを持つオブジェクトで「getProgram」を呼び出せるようにしたいと考えています。ここでインターフェイスを使用する必要があることはわかっていますが、他の人のコードを使用していて、使用しているクラスを再設計できません。BeanUtils.getProperty が役立つかもしれないと思ったのですが、文字列しか返さないようです。キャスト可能なオブジェクトを返す Beanutils.getProperty のようなものはありますか? または、インターフェイスを共有しない 2 つの類似したクラスを操作する別のよりスマートな方法はありますか? ありがとう -モーガン

4

7 に答える 7

5

BeanUtils の代わりに PropertyUtils (apache commons-beanutils から) を使用します。

String の代わりに Object を返す getProperty(Object bean, String name) メソッドがあります。

詳細については、JavaDocを参照してください。

于 2009-01-27T16:32:18.650 に答える
2

これにはリフレクションを使用してください...次の例は、共通のインターフェースを持たないオブジェクトでそれを行う方法を示しています。

    public static void main(String[] args) throws Exception {
    doSomething(new A());
    doSomething(new B());
}

private static void doSomething(Object object) throws Exception {
    Method m = object.getClass().getMethod("doSomething", (Class[])null);
    m.invoke(object, (Object[])null);
}

private static class A {
    public void doSomething() {
        System.out.println("I'm doing it already!");
    }
}

private static class B {
    public void doSomething() {
        System.out.println("I'm doing it too!");
    }
}
于 2009-01-27T16:14:03.977 に答える
0

Java 5+ を使用している場合は、わずかに短いバージョン

public static void main(String[] args) throws Exception {
    System.out.println(invoke("toString", new A());
    System.out.println(invoke("toString", new B());
}

private static <R> R invoke(Object object, String methodName) throws Exception {
    return (R) object.getClass().getMethod(methodName).invoke(object);
}
于 2009-01-27T19:56:52.513 に答える
0

おそらく、このメソッドを実装するクラスの数は有限であり、それらに直接リンクできます。だから反省はいらない。反射は悪です。

次のメソッドを持つ一連のクラスがあるとします。

public class LibA { public Program getProgram() { return program; } ... };
public class LibB { public Program getProgram() { return program; } ... };
...

次に、インスタンスとキャストのペアが必要です。これをメソッドに入れると、一度だけ実行する必要があります。

public static Program getProgram(Object obj) {
    if        (obj instanceof LibA) {
        return              ((LibA)obj).getProgram();
    } else if (obj instanceof LibB) {
        return              ((LibB)obj).getProgram();
    } else {
        throw new IllegalArgumentException(obj+" doesn't have a known getProgram");
            // Or an appropriate application exception.
    }
}

または、アダプターを使用することもできます。

public interface ProgramContainer { 
    Program getProgram();
    ...
}

public class LibAContainer implements ProgramContainer {
    private final LibA libA;
    public LibAContainer(LibA libA) {
        this.libA = libA;
    }
    public Program getProgram() {
        return libA.getProgram();
    }
    ...
}
于 2009-01-27T16:39:08.340 に答える
0

リフレクション APIを参照してください。

Class.getMethod() (または getMethods()) を使用して、適切なメソッドを見つけて呼び出します。

于 2009-01-27T16:11:41.157 に答える
0

非常に単純な解決策: インターフェイスを実装する委任を使用します。

interface GetProgram
{
    String getProgram ();
}

class AWrapper implements GetProgram
{
    A a;
    public AWrapper (A a) { this.a = a;
    String getProgram () { return a.getProgram(); }
}

これで、元のクラスに触れることなく、コードでインターフェイスを使用できます。

欠点: A が手の届かない場所に作成されている場合、これはうまく機能しません。A が一度自分の管理下で作成され、すぐにラップできる場合に最適です。

于 2009-01-27T16:59:57.720 に答える
-1

java.beans.Expressionは、レシーバーの具象クラスでメソッドにアクセスできる限り、これを実行します。

public static void main(String[] args) throws Exception {
    new Expression(new A(), "doSomething", null).getValue();
    new Expression(new B(), "doSomething", null).getValue();
}

public static class A {
    public void doSomething() {
            System.out.println("I'm doing it already!");
    }
}

public static class B {
    public void doSomething() {
            System.out.println("I'm doing it too!");
    }
}
于 2009-01-27T16:22:31.947 に答える