57

先日、クラスの各要素を手動で文字列に書き出すことで Java のクラスの toString() を書いていたところ、リフレクションを使用して、機能する汎用の toString() メソッドを作成できる可能性があることに気付きました。すべてのクラスで。つまり、フィールド名と値を把握し、それらを文字列に送信します。

フィールド名を取得するのはかなり簡単です。同僚が思いついたのは次のとおりです。

public static List initFieldArray(String className) throws ClassNotFoundException {

    Class c = Class.forName(className);
    Field field[] = c.getFields();
    List<String> classFields = new ArrayList(field.length);

    for (int i = 0; i < field.length; i++) {
        String cf = field[i].toString();
        classFields.add(cf.substring(cf.lastIndexOf(".") + 1));
    }

    return classFields;
}

ファクトリを使用すると、最初に toString() が呼び出されたときにフィールドを 1 回格納することで、パフォーマンスのオーバーヘッドを削減できます。ただし、値を見つけるには、はるかにコストがかかる可能性があります。

リフレクションのパフォーマンスが原因で、これは実際的というよりも仮説的なものになる可能性があります。しかし、リフレクションのアイデアと、それを使って日常のプログラミングを改善する方法に興味があります。

4

7 に答える 7

6

私はapacheライブラリに気づいていなかったので、振り返りがあります:

(これを行う場合、おそらくサブオブジェクトを処理し、それらが適切に印刷されることを確認する必要があることに注意してください。特に、配列は有用なものを表示しません)

@Override
public String toString()
{
    StringBuilder b = new StringBuilder("[");
    for (Field f : getClass().getFields())
    {
        if (!isStaticField(f))
        {
            try
            {
                b.append(f.getName() + "=" + f.get(this) + " ");
            } catch (IllegalAccessException e)
            {
                // pass, don't print
            }
        }
    }
    b.append(']');
    return b.toString();
}


private boolean isStaticField(Field f)
{
    return Modifier.isStatic(f.getModifiers());
}
于 2009-01-14T18:23:17.223 に答える
5

Eclipse を使用している場合は、静的に (ソース コードでメソッドを生成する) JUtils toString generatorも参照してください。

于 2009-01-14T17:00:42.117 に答える
4

リフレクションではありませんが、バイトコード操作を使用してコンパイル後のステップとして toString メソッドを (equals/hashCode と共に) 生成する方法を調べました。結果はまちまちでした。

于 2009-01-14T18:17:35.113 に答える