3

私はこのコードを使用しようとします (更新m_set は、異なる型引数を使用するいくつかのメソッドを通過する for ループ内で使用されます。たとえば、 int.class を に追加するとgetMethod、1 回の反復後にエラーが発生します。次のメソッドには文字列が必要なためです。 .class. リフレクションを使用してこのような問題を解決することは可能ですか?):

Method m_set = product.getClass().getMethod(method_name);
m_set.invoke(product, method_value);

次のエラーが表示されます。

 Exception in thread "main" java.lang.NoSuchMethodException: test.NormalChair.setHeight()
        at java.lang.Class.getMethod(Class.java:1655)
        at test.ProductTrader.create(ProductTrader.java:68)
        at test.Test.main(Test.java:32)

エラーでは、このメソッドを使用するクラスでメソッドを見つけようとしていることを示しています。しかし、そのメソッドは親クラスにあり、パブリック メソッドです。を使用するかどうかはわかってgetDeclaredMethodいますが、同様のエラーが発生しますが、なぜこのエラーが発生するのgetMethodですか?

私のクラスにはこのメソッドがあります:

public abstract class AbstractChair {
    public String name;
    public int height;
    public AbstractChair() {
    }

    public AbstractChair(String name, int height){
        this.name = name;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }   
}

このメソッドを使用しようとするクラス:

public class NormalChair extends AbstractChair {
    public NormalChair() {
        super();
    }

    public NormalChair(String name, int height) {
        super(name, height);
    }


    // Copy constructor
    public NormalChair(NormalChair chair) {
      this(chair.getName(), chair.getHeight());
    }

}

Update2

私がこのようなことをすると:

if(method_name == "setHeight"){
  Method m_set = product.getClass().getMethod(method_name, int.class);
  m_set.invoke(product, method_value);
}
else if (method_name == "setName")
{
  Method m_set = product.getClass().getMethod(method_name, String.class);
  m_set.invoke(product, method_value);
}

するとエラーが消えます。誰かがより普遍的なアプローチを提案できますか?

4

2 に答える 2

10

メソッドが必要とする引数の型を渡すのを忘れたようです (メソッドは異なる引数型でオーバーロードできることに注意してください)。コードを見てください。setHeight()メソッドはありませんが、 setHeight(int). 次のようなものを試してみてください

Method m_set = product.getClass().getMethod(method_name,method_value.getClass());
m_set.invoke(product, method_value);

プリミティブ型で問題が発生する可能性があるため、回避策を使用できます。見つけたいクラスに同じ名前のメソッドが 1 つだけあると仮定すると、すべてのパブリック メソッドを反復処理し、その名前を探しているメソッドと比較して、必要な引数で呼び出すことができます。何かのようなもの

Method[] methods = product.getClass().getMethods();
for (Method m : methods){
    System.out.println(m);
    if (m.getName().equals("setHeight")){
        m.invoke(product, method_value);
        break;
    }
}

別のおそらくより良い方法は、java.beanのようなパッケージのクラスを使用することPropertyDescriptorです。このクラスのおかげで、特定のプロパティのゲッターとセッターを見つけることができます。プロパティ forsetHeightは次のheightように使用する必要があることに注意してください

Method setter = new PropertyDescriptor("height", product.getClass()).getWriteMethod();
setter.invoke(product, method_value);
于 2013-11-11T19:13:44.047 に答える
4

を使用しproduct.getClass().getMethod("setHeight", int.class);ます。メソッド シグネチャをターゲットにするには、メソッド パラメーターの型を渡す必要があります。

于 2013-11-11T19:13:41.380 に答える