web-dev-qa-db-ja.com

"SomeType @ 2f92e0f4"を取得せずに自分のJavaオブジェクトを印刷する方法を教えてください。

次のように定義されたクラスがあります。

public class Person {
  private String name;

  // constructor and getter/setter omitted
}

私は自分のクラスのインスタンスを印刷しようとしました:

System.out.println(myPerson);

しかし、私は次のような出力を得ました:com.foo.Person@2f92e0f4

Personオブジェクトの配列を印刷しようとしたときにも同様のことが起こりました。

Person[] people = //...
System.out.println(people); 

私は出力を得ました:[Lcom.foo.Person;@28a418fc

この出力はどういう意味ですか?私の人の名前が含まれるようにこの出力を変更するにはどうすればよいですか?そしてどのように私は私のオブジェクトのコレクションを印刷するのですか?

:これは、この問題に関する正規のQ&Aとして書かれています。

266
Duncan Jones

バックグラウンド

すべてのJavaオブジェクトにはtoString()メソッドがあります。このメソッドは、オブジェクトを試して印刷するときに呼び出されます。

System.out.println(myObject);  // invokes myObject.toString()

このメソッドは Object クラス(すべてのJavaオブジェクトのスーパークラス)で定義されています。 Object.toString() メソッドは、クラス名、@シンボル、およびオブジェクトの hashcode で構成される、かなり見苦しい文字列を16進数で返します。このコードは次のようになります。

// Code of Object.toString()
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

したがって、com.foo.MyType@2f92e0f4のような結果は次のように説明できます。

  • com.foo.MyType - クラスの名前。つまり、パッケージcom.fooではクラスはMyTypeです。
  • @ - 文字列を結合します
  • 2f92e0f4はオブジェクトのハッシュコードです。

配列クラスの名前は少し違って見えますが、これはJavadocの Class.getName() でよく説明されています。たとえば、[Ljava.lang.Stringは次のようになります。

  • [ - ([[[[[などとは対照的に)1次元配列
  • L - 配列はクラスまたはインタフェースを含みます
  • Java.lang.String - 配列内のオブジェクトの型

出力をカスタマイズする

System.out.println(myObject)を呼び出したときに別のものを出力するには、自分のクラスのtoString()メソッドを override オーバーライドする必要があります。これは簡単な例です:

public class Person {

  private String name;

  // constructors and other methods omitted

  @Override
  public String toString() {
    return name;
  }
}

Personを印刷すると、com.foo.Person@12345678ではなくその名前が表示されます。

toString()はオブジェクトを文字列に変換するための単なるone wayであることに注意してください。通常、この出力はあなたのオブジェクトを明確で簡潔な方法で完全に記述するべきです。私たちのPersonクラスのためのより良いtoString()は次のようになります。

@Override
public String toString() {
  return getClass().getSimpleName() + "[name=" + name + "]";
}

例えばPerson[name=Henry]のように表示されます。これはデバッグやテストに非常に役立つデータです。

オブジェクトの一面だけに焦点を当てたい場合や、たくさんのジャズフォーマットを含めたい場合は、代わりに別のメソッドを定義したほうがよいでしょう。 String toElegantReport() {...}


出力を自動生成する

多くの IDE は、クラス内のフィールドに基づいてtoString()メソッドの自動生成をサポートしています。たとえば、 Eclipse および IntelliJ のドキュメントを参照してください。

いくつかの人気のあるJavaライブラリもこの機能を提供しています。例をいくつか挙げます。


オブジェクトの印刷グループ

それであなたはあなたのクラスのためにNice toString()を作成しました。そのクラスが配列またはコレクションに配置されるとどうなりますか?

配列

オブジェクトの配列がある場合は、 Arrays.toString() を呼び出して配列の内容を簡単に表現することができます。たとえば、次のPersonオブジェクトの配列を考えてください。

Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));

// Prints: [Fred, Mike]

注意:これは、ArraysクラスのtoString()というstaticメソッドへの呼び出しです。これは、上で説明したものとは異なります。

多次元配列 がある場合は、 Arrays.deepToString() を使用して同じ種類の出力を実現できます。

コレクション

ほとんどのコレクションはすべての要素で.toString()を呼び出すことに基づいてきれいな出力を生成します。

List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));    
System.out.println(people);

// Prints [Alice, Bob]

そのため、上で説明したように、リスト要素にNice toString()が定義されていることを確認する必要があります。

355
Duncan Jones

私はApacheが文字列を取得する機能を提供するより良いutilクラスを提供すると思います

ReflectionToStringBuilder.toString(object)
43
Rohith K

JavaのすべてのクラスにはデフォルトでtoString()メソッドがあります。これは、そのクラスのオブジェクトをSystem.out.println()に渡すと呼び出されます。デフォルトでは、この呼び出しはそのオブジェクトのclassName @ハッシュコードを返します。

{
    SomeClass sc = new SomeClass();
    // Class @ followed by hashcode of object in Hexadecimal
    System.out.println(sc);
}

異なる出力を取得するためにクラスのtoStringメソッドをオーバーライドすることができます。この例を参照

class A {
    String s = "I am just a object";
    @Override
    public String toString()
    {
        return s;
    }
}

class B {
    public static void main(String args[])
    {
        A obj = new A();
        System.out.println(obj);
    }
}
26
Pankaj Manali

Eclipseで、自分のクラスに移動し、右クリック - > source - > Generate toString();

これはtoString()メソッドをオーバーライドし、そのクラスのオブジェクトを表示します。

8
Ketan Keshri

デフォルトでは、Javaのすべてのオブジェクトには、ObjectType @ HashCodeを出力するtoString()メソッドがあります。

もっと意味のある情報が必要な場合は、クラスのtoString()メソッドをオーバーライドする必要があります。

public class Person {
  private String name;

  // constructor and getter/setter omitted

  // overridding toString() to print name
  public String toString(){
     return name;  
  }
}

System.out.prtinln(personObj);を使用してpersonオブジェクトを印刷すると、クラス名とハッシュコードの代わりにpersonの名前が表示されます。

2番目のケースでは、配列を印刷しようとしているときに、[Lcom.foo.Person;@28a418fcをArray型とそのハッシュコードで出力します。


個人名を印刷したい場合は、さまざまな方法があります。

各人を繰り返して印刷する独自の関数を書くことができます

void printPersonArray(Person[] persons){
    for(Person person: persons){
        System.out.println(person);
    }
}

Arrays.toString()を使って印刷できます。これは私にとって最も簡単なようです。

 System.out.println(Arrays.toString(persons));
 System.out.println(Arrays.deepToString(persons));  // for nested arrays  

あなたはそれを(ストリームとメソッド参照を使って)Java 8の方法で印刷することができます。

 Arrays.stream(persons).forEach(System.out::println);

他の方法もあるかもしれません。お役に立てれば。 :)

4
adn.911

Intellijでは、alt + insetを押してtoString()を選択することでtoStringメソッドを自動生成できます。これはテストクラスの出力です。

public class test  {
int a;
char b;
String c;
Test2 test2;

@Override
public String toString() {
    return "test{" +
            "a=" + a +
            ", b=" + b +
            ", c='" + c + '\'' +
            ", test2=" + test2 +
            '}';
 }
}

ご覧のとおり、クラスの複数の属性を連結してStringを生成します。プリミティブの場合は値を出力し、参照型の場合はクラス型を使用します(この場合はTest2の文字列メソッド)。

4
Mr.Q

JavaオブジェクトをJSON文字列にデシリアライズするために _ gson _ を使用するユーティリティ関数を使用することを好みます。

/**
 * This class provides basic/common functionalities to be applied on Java Objects.
 */
public final class ObjectUtils {

    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();

    private ObjectUtils() {
         throw new UnsupportedOperationException("Instantiation of this class is not permitted in case you are using reflection.");
    }

    /**
     * This method is responsible for de-serializing the Java Object into Json String.
     *
     * @param object Object to be de-serialized.
     * @return String
     */
    public static String deserializeObjectToString(final Object object) {
        return GSON.toJson(object);
    }
}
3
Agam

Personのオブジェクトを直接印刷した場合、コードにはClassName@HashCodeが付きます。

あなたの場合はcom.foo.Person@2f92e0f4が印刷されます。ここでPersonはオブジェクトが属するクラス、2f92e0f4はオブジェクトのhashCodeです。

public class Person {
  private String name;

  public Person(String name){
  this.name = name;
  }
  // getter/setter omitted

   @override
   public String toString(){
        return name;
   }
}

Personのオブジェクトを使おうとすると、名前が表示されます。

Class Test
 {
  public static void main(String... args){
    Person obj = new Person("YourName");
    System.out.println(obj.toString());
  }
}
3
Vikrant Kashyap

Objectクラス(Javaの全クラスの親クラス)を見ると、toString()メソッドの実装は次のようになります。

    public String toString() {
       return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

javaでオブジェクトを印刷するたびにtoString()が呼び出されます。 toString()をオーバーライドしても、他のObjectクラスのメソッド呼び出しが呼び出されるようになります。