2

職場では、週に数回パラメーターを変更するクライアントのレポートを生成する必要があります。このレポートは、データベースの単一のテーブルから生成されます。たとえば、100 列のテーブルがあり、今日は 5 列のみのレポートを生成する必要があり、明日は 95 列で生成する必要があるとします。これを念頭に置いて、指定されたテーブルのすべての列を持つ TO クラスを作成し、クエリはすべての列 (SELECT * FROM TABLE) を返します。

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

すべての列が TO クラスの属性と同じ名前を持っているため、次のコードを開発しました (これは 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 クラスの getter には、パターン "getAttribute_Name" があります。

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

4

2 に答える 2

0

私のJavaはもう少し制限がありますが、リフレクションを使用するのと同じくらい良いと思います.

Class<?> c = Test.class;

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

しかし、これは潜在的に信頼できないデータからのもののように聞こえるためHashMap、この場合は各メソッドを明示的に参照して a を使用することをお勧めします。まず、動的に呼び出すことができるメソッドを明示的に示します。2 つ目は、よりタイプ セーフであり、コンパイル時エラーは実行時エラーよりもはるかに優れています。第三に、反射を完全に回避するため、おそらく高速です。これの効果に何か:

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 違反のように聞こえるかもしれませんが、少なくとも繰り返しによって、関係のない getter が誤って呼び出されることを防ぐことができます。

于 2016-05-02T22:50:26.197 に答える