2017-04-12 1 views
3

私はライブラリ関数(理想的には、Spring、Guava、Apache Commonsなどの一般的に使用されるフレームワーク)を探しています。これはJavaオブジェクトの値をうまく印刷します。複雑なJavaオブジェクト(オブジェクトのコレクションであるフィールドなど)をきれいに印刷するにはどうすればよいですか?

これは特定の質問ではなく一般的な質問です。 StackOverflowで共通の答えが「クラスに独自のtoString()メソッドを実装する」という同様の質問がありましたが、このオプションは必ずしも実用的ではありません。私が出会うすべてのオブジェクトでこれを行う一般的な方法を探していますサードパーティのコードから。もう一つの提案は、ApacheのコモンズからRefectionToStringBuilderを使用することです例えば:

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

しかし、これは限られた用途を持っている - 例えばそれが出力する傾向がコレクションに遭遇すると、このような何か:実際の使用例は、JGitのpushCommand.call()メソッドから返されたIterable<PushResult>をログに記録することです

[email protected][size=1] 

- 答えを投稿した場合、それはこので動作するだろうことを確認してください他の複雑なオブジェクトと同様に。

+3

ない何をしたいが、あなたはJSONにシリアライズし、JSON(またはYAMLまたは任意の形式であなたが好きなの)かなり-印刷する – assylias

+0

ありがとう@assyliasをJSONライブラリを使用することができ、このかもしれません助けてください。多分、使用例を教えてください。 –

+1

私は前に 'ReflectionToStringBuilder'を使ったことはありませんでしたので、これを答えとして投稿するつもりはありませんが、' getValue'メソッドをオーバーライドして 'Collection'フィールドとして(またはあなた自身の 'String'バージョンのコレクションでさえ)与えられます。 – Zircon

答えて

0

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" ] 
} 
+0

これは有望ですが、残念なことに、この例の使用例では、次のエラーが発生しました: 'com.fasterxml.jackson.databind.JsonMappingException:サイクルにつながる直接自己参照(参照チェーンを通じて:java.util.ArrayList [0] - > org.eclipse.jgit.transport.PushResult ["advertisedRefs"] - > java.util.Collections $ UnmodifiableCollection [0] - > org.eclipse.jgit.lib.ObjectIdRef $ PeeledNonTag ["leaf"]) ' –

+0

@SteveChambers Cyclical参照はあなたが持っているときです: 'class A {私的な親; } '例えば。どんな解決策が見つかったとしても、少しでも助けを借りれば、そのような状況に対処することはほとんどありません。ジャクソンには[JsonIdentityInfo annotation](http://stackoverflow.com/a/9673890/829571)があります。 – assylias

1

あなたがしようとするとGsonを使用することができます。それはまた、アレイ、地図や直列化復元の使用のために何でも....

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

をシリアライズ:

gson.fromJson(MyObject.class); 

型指定されたマップの場合、この答えを参照してください。Gson: Is there an easier way to serialize a map

0

あなたのオブジェクトを変換するためにGSONを使用することができます文字列に。これは、あなたがObjectMapperクラスを使用することができ、すべてのオブジェクトに対して

Gson gson = new Gson(); 
System.out.println(gson.toJson(objectYouWantToPrint).toString()); 
+0

おっと!訂正してくれてありがとう。 @JacobG。 – Vijayakumar

0

に動作しますJSONでデータをバインドするために使用されます。あなたは以下のようにそれを使用することができます:

ObjectMapper mapper = new ObjectMapper(); 

は、あなたはそれが正常に動作する必要があり

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

変数の文字列でそれを書くことができます

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

の下のようなオブジェクトにJSONを保存することができます。

+0

'Iterable 'の 'mapper.readValue'コールを拡張することができますか?オーバーロードが使用され、何が渡されるべきですか? –

0

外部ライブラリを使用しないオブジェクトに対してこれを実行する方法の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をオーバーライドしない場合は、単にオブジェクトのタイプとそのhashCodeを出力します。

例:おそらく

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]] 
+0

これは現在、オブジェクトであるコレクションまたはフィールドには再帰しません。理想的には、ユニットテストなどのオーバーヘッドを必要としないライブラリメソッドが好きであり、必要に応じてDisplayウィンドウで使用できるようにしたいと考えています。 –

+0

@SteveChambers私はそれをネストした 'Collection'sでテストしました。私はそれを証明するために例を変えました! –

+0

これをテストしました:http://rextester.com/GXUV44108私はコレクションの部分(少なくともリストの部分)で修正されているようですが、残念ながらオブジェクトに再帰しません(例えば 'test2:Rextester $ Test2 @ 6d06d69c' )。 –

関連する問題