「SomeType @ 2f92e0f4」を取得せずにJavaオブジェクトを印刷するにはどうすればよいですか?


301

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

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として意図されています。


1
GSONライブラリを使用して、オブジェクトをjsonに、またはその逆に変換できます。デバッグに非常に役立ちます。
Ashish Rawat

回答:


403

バックグラウンド

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

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

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

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

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

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

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

  • [- (とは対照的に、単一次元アレイ[[又は[[[等)
  • L -配列にはクラスまたはインターフェースが含まれます
  • java.lang.String -配列内のオブジェクトのタイプ

出力のカスタマイズ

お電話の際は別の何かを印刷するにはSystem.out.println(myObject)、あなたがしなければならないオーバーライドしtoString()、独自のクラスのメソッドを。以下に簡単な例を示します。

public class Person {

  private String name;

  // constructors and other methods omitted

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

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

これtoString()は、オブジェクトを文字列に変換する方法の1つにすぎないことに注意してください。通常、この出力では、オブジェクトを明確かつ簡潔に完全に説明する必要があります。toString()私たちのPersonクラスにとってより良いのは:

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

これは、たとえばを印刷しますPerson[name=Henry]。これは、デバッグ/テストに非常に役立つデータです。

オブジェクトの1つの側面のみに焦点を当てる場合、または多くのジャジーなフォーマットを含める場合は、代わりに別のメソッドを定義することをお勧めしますString toElegantReport() {...}


出力の自動生成

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

いくつかの人気のあるJavaライブラリもこの機能を提供しています。いくつかの例は次のとおりです。


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

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

配列

オブジェクトの配列がある場合は、を呼び出しArrays.toString()て、配列の内容の単純な表現を生成できます。たとえば、次のPersonオブジェクトの配列を考えてみます。

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

// Prints: [Fred, Mike]

注:これは、Arraysクラスで呼び出される静的メソッドの呼び出しtoString()であり、これまでに説明してきたものとは異なります。

あなたが持っている場合は多次元配列を、あなたが使用することができ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]

したがって、toString()上記のようにリスト要素がnice を定義していることを確認する必要があるだけです。


return String.format( getClass().getSimpleName() + "[ name=%s ]", name);実際には代わりにnameゲッターを使用する必要がありますgetName()(ただし、ゲッターはPersonクラスで省略されていました...)ゲッターが使用された場合...return String.format( getClass().getSimpleName() + "[ name=%s ]", getName());
CrandellWS

javaファイルに2つのクラスがある場合、パブリックでないクラスのオブジェクトを作成する方法A.javaパブリッククラスA {}クラスB {} ------ C.javaパブリッククラスC {A a = new A( ); }
yatinbc 2016年

のオーバーロードバージョンがあるArrays.toString()ため、プリミティブの配列にも使用できることに注意してください(int[]double[])。また、Arrays.deepToString()素敵なプリミティブの多次元配列を処理します。
Ole VV

1
@ MasterJoe2わからない、おそらく彼らは負の値を文字列にエンコードしようとすると醜く見えると思いましたか?
ダンカンジョーンズ

55

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

ReflectionToStringBuilder.toString(object)

5
これには、クラスを編集する必要がないという利点があります。しかし、ネストされたオブジェクトを再帰的に印刷するにはどうすればよいですか?
lukas84

35

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

{
    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);
    }
}

3
これは適切で短い回答ですが、OPが[Lcom.foo.Person;@28a418fc出力として取得される理由を明確にするためです。これtoString()もメソッドの出力ですが、実行時に型に対して生成されるクラスに実装されるものであり、型Person[]ではありませんPersonstackoverflow.com/a/8546532/1542343)。
gvlasov 2015年

この出力は、package.Class @ Hashcodeを意味します。デフォルトのtoString()メソッドには、次のような戻り値の型があります。Object.hasCode()またはクラス名とともに16進数形式のハッシュコードを返す同様のreturnステートメントを返します。
Pankaj

14

Eclipseで、クラスに移動し、右クリック->ソース->生成toString();

toString()メソッドをオーバーライドし、そのクラスのオブジェクトを出力します。


10

私は、GSONを使用してJavaオブジェクトをJSON文字列に逆シリアル化するユーティリティ関数を使用することを好みます。

/**
 * 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);
    }
}

それはそうreturn Gson.toJson(object);でなければ、そうでなければ完璧に動作します。
Nakrule

それだけです。
アガム

5

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 +
            '}';
 }
}

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


4

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

より意味のある情報が必要な場合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);て人物オブジェクトを印刷すると、クラス名とハッシュコードの代わりに人物の名前が印刷されます。

2番目のケースでは、配列を出力しようとすると、配列[Lcom.foo.Person;@28a418fcタイプとハッシュコードが出力されます。


個人名を印刷したい場合は、いくつかの方法があります。

各人を反復して出力する独自の関数を書くことができます

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);

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


3

Personのオブジェクトを直接印刷する場合は、それがClassName@HashCodeコードになります。

あなたの場合com.foo.Person@2f92e0f4は印刷されています。どこにPersonオブジェクトが属し、先のクラスである2f92e0f4Objectのハッシュコードです。

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());
  }
}

2

Objectクラス(Javaのすべてのクラスの親クラス)を見ると、toString()メソッドの実装は

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

Javaでオブジェクトを出力すると、必ずtoString()が呼び出されます。これで、toString()をオーバーライドするかどうかはあなた次第です。次に、メソッドが他のObjectクラスのメソッド呼び出しを呼び出します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.