9

こんにちは私は何かを達成するためにリフレクションを使用しています。クラス名、そのクラスのメソッド名、およびファイル内のそのメソッドに渡す必要があるパラメーター値が与えられています(任意のファイルを取得します。制約ではありません)。パラメータを指定してそのメソッドを呼び出す必要があります。このメソッドは何も返しません。このクラスにはメソッドの膨大なリストがあり、それぞれのパラメーター リストはさまざまです。

例:method1(String, String, int, boolean) method1(String, int, boolean)同様に、さまざまな順列と組み合わせがあります。では、どうすればこれを達成できますか。さまざまな switch 句を使用してハード コーディングを試みましたが、これは実際のオーバーヘッドであり、維持するのは危険です。その場でファイルからメソッド名とそのパラメーターを読み取って呼び出すように、これを動的に行うことはできますか。どんな小さなコード スニペットでも役に立ちます。ティア。

4

4 に答える 4

3
public class ReflectionSample
{
    private Object mString = null;
    private int mValue;

    public ReflectionSample()
    {
    }

    public ReflectionSample(int oValue)
    {
        mValue = oValue;
    }

    public ReflectionSample(String oString)
    {
        mString = oString;
    }

    public ReflectionSample(String oString, int oValue)
    {
        setValues(oString, oValue);
    }

    public void setValues(String oString, int oValue)
    {
        mString = oString;
        mValue = oValue;
    }

    public String toString()
    {
        return ""+mString+":"+mValue;
    }

    public void run()
    {
        String oInput = "Teststring";
        Class<?> cls;
        String clsname = "main.ReflectionSample";
        Object rs = null;   // ReflectionSample
        Object rsc = null;

        System.out.println(this.getClass().getName());
        try
        {
            System.out.println(clsname);
            cls = Class.forName(clsname);
            if(cls == null)
            {
                System.err.println(clsname + " doesn't exist");
                return;
            }

            // Look for a constructor which has a single string
            Constructor<?> ct = null;
            Class<?>[] param_types = new Class<?>[1];
            Object[] arguments = new Object[1];

            param_types[0] = String.class;

            // get the string constructor
            ct = cls.getConstructor(param_types);

            // We only have one object
            arguments = new Object[1];
            arguments[0] = oInput;

            // Instantiate the object with passed in argument.
            rs = ct.newInstance(arguments);
            System.out.println("String constructor sample: "+rs);

            // Instantiate with default constructor
            param_types = new Class<?>[0];
            arguments = new Object[0];
            ct = cls.getConstructor(param_types);
            rs = ct.newInstance(arguments);
            rsc = rs; // Keep it for later, to lazy to call it again
            System.out.println("Default constructor sample: "+rs);

            // Instantiate with string and int constructor
            param_types = new Class<?>[2];
            arguments = new Object[2];

            // Must be in the same order as the params I think
            param_types[0] = String.class;
            param_types[1] = Integer.TYPE;      // <-- Its a primitive so use TYPE not Class

            arguments[0] = oInput;
            arguments[1] = new Integer(1);

            ct = cls.getConstructor(param_types);
            rs = ct.newInstance(arguments);
            System.out.println("String plus int constructor sample: "+rs);

            // call the setValues method
            param_types[0] = String.class;
            param_types[1] = Integer.TYPE;      // <-- Its a primitive so use TYPE not Class

            arguments[0] = oInput;
            arguments[1] = 1;

            System.out.println("setValues invocation before: "+rsc);
            Method m = cls.getMethod("setValues", param_types);
            m.invoke(rsc, arguments);
            System.out.println("setValues invocation after: "+rsc);

            // An alternative method to pass the parameters
            m = cls.getMethod("setValues", String.class, Integer.TYPE);
            m.invoke(rsc, oInput+"x", 2);
            System.out.println("setValues invocation after: "+rsc);
        }
        catch(Throwable e)
        {
            System.err.println(e.getLocalizedMessage());
        }
    }
}

出力:

main.ReflectionSample
main.ReflectionSample
String constructor sample: Teststring:0
Default constructor sample: null:0
String plus int constructor sample: Teststring:1
setValues invocation before: null:0
setValues invocation after: Teststring:1

お役に立てれば。

これが Java の新しい機能であるかどうかはわかりませんが、配列を使用する代わりにパラメーターを使用して呼び出しを使用できるようになったことを確認しました。これにより、コードが読みやすくなる可能性があります (これは別の方法です)。 . 可変数の引数が必要で、その数が事前にわからない場合、配列の割り当ては間違いなく機能しており、下位互換性も備えている必要があります。

于 2013-04-25T11:02:44.917 に答える
0

2 つの int パラメータの例を以下に示します。同様に、他のデータ型パラメータも呼び出すことができます

Method method=new Test1().getClass().getMethod(x, new Class[] {int.class,int.class});

int,int,string以下のように、3 つの引数を必要とするメソッドを呼び出すことができます。

Method method=new Test1().getClass().getMethod(x, new Class[] {int.class,int.class, String.class});
于 2020-10-30T15:51:08.727 に答える