web-dev-qa-db-ja.com

複雑なJavaオブジェクトをきれいに印刷する方法(たとえば、オブジェクトのコレクションであるフィールドを使用))?

私はライブラリ関数を探しています(理想的には、一般的に使用されるフレームワーク(たとえば、Spring、Guava、Apache Commonsなど)から)。任意Javaオブジェクト。

これは特定の問題ではなく、一般的な問題です。 StackOverflowで同様の質問を見たことがありますが、一般的な答えは「クラスに独自のtoString()メソッドを実装する」ですが、このオプションは必ずしも実用的ではありません-オブジェクトIでこれを行う一般的な方法を探していますサードパーティのコードが原因である可能性があります。別の提案は、Apache Commonsの RefectionToStringBuilder を使用することです。

_new ReflectionToStringBuilder(complexObject, new RecursiveToStringStyle()).toString()
_

しかし、これには使用の制限があります。コレクションに出くわすと、次のようなものが出力される傾向があります。

_Java.util.ArrayList@fcc7ab1[size=1]
_

実際のユースケースの例は、JGitの pushCommand.call() メソッドから返される _Iterable<PushResult>_ をログに記録することです-回答を投稿する場合は、それが機能することを確認してくださいこれだけでなく、他の複雑なオブジェクトでも。

8
Steve Chambers

Gsonを試して使用することができます。また、配列、マップなどをシリアル化します。

MyObject myObject = new MyObject();
Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();
gson.toJson(myObject);

逆シリアル化を使用する場合:

gson.fromJson(MyObject.class);

型付きマップについては、この回答を参照してください: Gson:マップをシリアル化する簡単な方法はありますか

5
Naxos84

外部ライブラリを使用せずにオブジェクトに対してこれを行う1つの可能な方法は、ジェネリック型のリフレクションを使用することです。次のスニペットでは、各フィールド(プライベートフィールドを含む)にアクセスし、その名前と値を出力します。

public static <T> String printObject(T t) {
    StringBuilder sb = new StringBuilder();

    for (Field field : t.getClass().getDeclaredFields()) {
        field.setAccessible(true);

        try {
            sb.append(field.getName()).append(": ").append(field.get(t)).append('\n');
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return sb.toString();
}

このメソッドは、簡単にアクセスできるようにユーティリティクラスに配置できます。

オブジェクトのフィールドのいずれかがObject#toStringをオーバーライドしない場合は、オブジェクトのタイプとそのハッシュコードを出力するだけです。

例:

public class Test {

    private int x = 5;

    private int y = 10;

    private List<List<Integer>> list = Arrays.asList(Arrays.asList(1, 2, 3), Arrays.asList(4, 5, 6));

}

>> printObject(new Test());
>>
>> x: 5
>> y: 10
>> list: [[1, 2, 3], [4, 5, 6]]
2
Jacob G.

JSON(または他の形式)マッパーを使用して、オブジェクトをきれいに出力できます。ほとんどの「標準」フィールド(プリミティブ、文字列、コレクション、マップ、配列など)を処理し、それができない場合は常にカスタムシリアライザーを追加できます。

たとえば、ジャクソンを使用すると、次のように簡単になります。

public static void main(String... args) throws Exception {
  ObjectMapper om = new ObjectMapper();
  om.enable(SerializationFeature.INDENT_OUTPUT); //pretty print
  String s = om.writeValueAsString(new Pojo());
  System.out.println(s);
}


static class Pojo {
  private int id = 1;
  private List<String> list = Arrays.asList("A", "B");
  //getters etc.
}

そのコードは出力します:

{
  "id" : 1,
  "list" : [ "A", "B" ]
}
1
assylias

GSONを使用して、オブジェクトを文字列に変換できます。これはすべてのオブジェクトで機能し、

Gson gson = new Gson();
System.out.println(gson.toJson(objectYouWantToPrint).toString());
1
Vijayakumar

ObjectMapperクラスを使用して、データをjsonにバインドできます。以下のように使用できます:

ObjectMapper mapper = new ObjectMapper();

以下のようにjsonをオブジェクトに保存できます

Object json = mapper.readValue(input,object.class);

あなたはそれを文字列変数に書くことができます

String prettyJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);

正常に動作するはずです。

1
Sagar Trivedi