2016-04-30 4 views
2

仕事中に、週に何回かパラメータを変更するクライアント用のレポートを生成する必要があります。 このレポートは、データベース上の単一のテーブルから生成されます。 たとえば、100列のテーブルを想像してみてください。今日は5列しかないレポートを生成する必要がありますが、明日はそれらを使って95を生成する必要があります。 これを念頭において、指定したテーブルのすべての列を含むTOクラスを作成し、クエリはすべての列(SELECT * FROM TABLE)を返します。Javaで動的にメソッドを呼び出す

私が作成しようとしているのは、レポートを生成する動的フォームです。 私は最初に、チェックボックスとして列挙された列のリストを持つ単純なフレームを作成し、ユーザーが望む列を選択することを考えました(もちろん、すべてを選択するボタンと他のすべてを選択解除するボタン)。すべての列として

は、クラスの属性と同じ名前を持って、私は次のコード(私はGoogleのこれを持って)開発:

Class c = Test.class; 

for(int i = 0; i < listOfAttributes.length; i++) 
{ 
    auxText += String.valueOf(c.getMethod("get" + listOfAttributes[i]).invoke(this, null)); 
} 

をこれは私が必要なものを行うには良い方法ですに?

ありがとうございます。

Obs:TOクラスのゲッターは、パターン "getAttribute_Name"を持ちます。

注:この質問は、特定の名前が与えられたメソッドを呼び出す方法をユーザーが求めている場合とは異なります。私はそれを行う方法を知っています。私が尋ねるのは、これが私が説明した問題を解決するより良い方法であるかどうかです。

+1

可能性のある重複した[私はJavaのメソッドを呼び出すにはどうすればよいですメソッド名が文字列として与えられると?](http://stackoverflow.com/questions/160970/how-do-i-invoke-a-java-method-when-given-the-method-name-as-a -string) –

+0

私がノートで言ったように:この質問は、特定の名前が与えられたメソッドを呼び出す方法をユーザーが求めている質問とは異なります。私はそれを行う方法を知っています。私が尋ねるのは、これが私が説明した問題を解決するより良い方法であるかどうかです。 –

+0

私はそれを取り戻すつもりです。あなたのメモは私が最初にそれを見直した後に追加されたことに注意します。 –

答えて

0

Javaはもう少し限られていますが、リフレクションを使用するほど良いと思います。

Class<?> c = Test.class; 

for (String attribute : listOfAttributes) { 
    auxText += String.valueOf(c.getMethod("get" + attribute).invoke(this, null)); 
} 

しかし、それは潜在的に信頼できないデータからだように、これが聞こえる以来、私は明示的に参照される各方法で、この場合にはHashMapを使用して助言します。まず、動的に呼び出すことができるメソッドを明示します。第二に、より安全な型であり、コンパイル時エラーは実行時エラーよりも優れています。第三に、それは反射を完全に避けるので、より速い可能性が高い。この効果に何か:

private static final HashMap<String, Supplier<Object>> methods = new HashMap<>(); 

// Initialize all the methods. 
static { 
    methods.set("Foo", Test::getFoo); 
    methods.set("Bar", Test::getBar); 
    // etc. 
} 

private String invokeGetter(String name) { 
    if (methods.containsKey(name)) { 
     return String.valueOf(methods.get(name).get()); 
    } else { 
     throw new NoSuchMethodException(); 
    } 
} 

それはそうすることを主要なDRY違反のように聞こえるかもしれませんが、繰り返しが、少なくともあなたが誤って呼ばれる無関係なゲッターと羽目ないことを確認します。

0
Class c = Test.class; 
for(int i = 0; i < listOfAttributes.length; i++) 
{ 
    auxText += String.valueOf(c.getMethod("get" + listOfAttributes[i]).invoke(this, null)); 
} 

あなたは、Javaの豆を経てややエレガントIntrospector、およびPropertyDescriptorこれを行うことができますが、それはもう少し長いったらしいです:の

Map<String, Method> methods = new HashMap<>(); 
Class c = this.getClass(); // surely? 
for (PropertyDescriptor pd : Introspector.getBeanInfo(c).getPropertyDescriptors()) 
{ 
    map.put(pd.getName(), pd.getReadMethod(); 
} 
// 
for (int i = 0; i < listOfAttributes.length; i++) 
{ 
    Method m = methods.get(listOfAttributes[i]); 
    if (m == null) 
     continue; 
    auxText += String.valueOf(m.invoke(this, null)); 
} 
関連する問題