que - string tostring java
¿Cómo imprimo mi objeto Java sin obtener "SomeType @ 2f92e0f4"? (10)
Antecedentes
Todos los objetos Java tienen un método
toString()
, que se invoca cuando intenta imprimir el objeto.
System.out.println(myObject); // invokes myObject.toString()
Este método se define en la clase
Object
(la superclase de todos los objetos Java).
El método
Object.toString()
devuelve una cadena de aspecto bastante feo, compuesta por el nombre de la clase, un símbolo
@
y el
hashcode
del objeto en hexadecimal.
El código para esto se ve así:
// Code of Object.toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Un resultado como
com.foo.MyType@2f92e0f4
puede explicarse como:
-
com.foo.MyType
: el nombre de la clase, es decir, la clase esMyType
en el paquetecom.foo
. -
@
- une la cadena -
2f92e0f4
el2f92e0f4
del objeto.
El nombre de las clases de matriz se ve un poco diferente, lo que se explica bien en los Javadocs para
Class.getName()
.
Por ejemplo,
[Ljava.lang.String
significa:
-
[
- una matriz unidimensional (a diferencia de[[
o[[[
etc.[[[
etc.) -
L
: la matriz contiene una clase o interfaz -
java.lang.String
: el tipo de objetos en la matriz
Personalizando la salida
Para imprimir algo diferente cuando llama a
System.out.println(myObject)
, debe
override
el método
toString()
en su propia clase.
Aquí hay un ejemplo simple:
public class Person {
private String name;
// constructors and other methods omitted
@Override
public String toString() {
return name;
}
}
Ahora, si imprimimos una
Person
, vemos su nombre en lugar de
com.foo.Person@12345678
.
Tenga en cuenta que
toString()
es solo
una
forma de convertir un objeto en una cadena.
Por lo general, esta salida debe describir completamente su objeto de manera clara y concisa.
Un mejor
toString()
para nuestra clase
Person
podría ser:
@Override
public String toString() {
return getClass().getSimpleName() + "[name=" + name + "]";
}
Lo que imprimiría, por ejemplo,
Person[name=Henry]
.
Esa es una pieza de datos realmente útil para la depuración / prueba.
Si desea centrarse en un solo aspecto de su objeto o incluir un gran formato de jazz, es mejor que defina un método separado, por ejemplo,
String toElegantReport() {...}
.
Generando automáticamente la salida
Muchos
IDEs
ofrecen soporte para generar automáticamente un método
toString()
, basado en los campos de la clase.
Ver documentos para
Eclipse
e
IntelliJ
, por ejemplo.
Varias bibliotecas populares de Java también ofrecen esta característica. Algunos ejemplos incluyen:
-
Anotación
@ToString
del Proyecto Lombok
Imprimir grupos de objetos
Entonces has creado un bonito
toString()
para tu clase.
¿Qué sucede si esa clase se coloca en una matriz o una colección?
Matrices
Si tiene una matriz de objetos, puede llamar a
Arrays.toString()
para producir una representación simple de los contenidos de la matriz.
Por ejemplo, considere esta matriz de objetos
Person
:
Person[] people = { new Person("Fred"), new Person("Mike") };
System.out.println(Arrays.toString(people));
// Prints: [Fred, Mike]
Nota: esta es una llamada a un método
estático
llamado
toString()
en la clase Arrays, que es diferente a lo que hemos estado discutiendo anteriormente.
Si tiene una
matriz multidimensional
, puede usar
Arrays.deepToString()
para lograr el mismo tipo de salida.
Colecciones
La mayoría de las colecciones producirán una salida bonita basada en llamar a
.toString()
en cada elemento.
List<Person> people = new ArrayList<>();
people.add(new Person("Alice"));
people.add(new Person("Bob"));
System.out.println(people);
// Prints [Alice, Bob]
Por lo tanto, solo debe asegurarse de que los elementos de su lista definan un agradable
toString()
como se discutió anteriormente.
Tengo una clase definida de la siguiente manera:
public class Person {
private String name;
// constructor and getter/setter omitted
}
Traté de imprimir una instancia de mi clase:
System.out.println(myPerson);
pero obtuve el siguiente resultado:
com.foo.Person@2f92e0f4
.
Algo similar ocurrió cuando intenté imprimir una matriz de objetos
Person
:
Person[] people = //...
System.out.println(people);
[Lcom.foo.Person;@28a418fc
la salida:
[Lcom.foo.Person;@28a418fc
¿Qué significa esta salida? ¿Cómo cambio esta salida para que contenga el nombre de mi persona? ¿Y cómo imprimo colecciones de mis objetos?
Nota : esto pretende ser un Q&A canónico sobre este tema.
Cada clase en Java tiene el método
toString()
por defecto, que se llama si pasa algún objeto de esa clase a
System.out.println()
.
Por defecto, esta llamada devuelve el className @ hashcode de ese objeto.
{
SomeClass sc = new SomeClass();
// Class @ followed by hashcode of object in Hexadecimal
System.out.println(sc);
}
Puede anular el método toString de una clase para obtener una salida diferente. Mira este ejemplo
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);
}
}
Creo que apache proporciona una mejor clase de utilidad que proporciona una función para obtener la cadena
ReflectionToStringBuilder.toString(object)
En Eclipse, vaya a su clase, haga clic derecho-> fuente-> Generar
toString()
;
toString()
método
toString()
e imprimirá el objeto de esa clase.
En intellij puede generar automáticamente el método toString presionando alt + recuadro y luego seleccionando toString () aquí hay una salida para una clase de prueba:
public class Person {
private String name;
// constructor and getter/setter omitted
// overridding toString() to print name
public String toString(){
return name;
}
}
Como puede ver, genera una Cadena al concatenar varios atributos de la clase, para las primitivas imprimirá sus valores y para los tipos de referencia usará su tipo de clase (en este caso, el método de cadena de Test2).
Por defecto, cada objeto en Java tiene el método
toString()
que genera el ObjectType @ HashCode.
Si desea información más significativa, debe anular el método
toString()
en su clase.
void printPersonArray(Person[] persons){
for(Person person: persons){
System.out.println(person);
}
}
Ahora, cuando imprime el objeto persona usando
System.out.prtinln(personObj);
imprimirá el nombre de la persona en lugar del nombre de clase y el código hash.
En su segundo caso, cuando intenta imprimir la matriz, imprime
[Lcom.foo.Person;@28a418fc
el tipo de matriz y su
[Lcom.foo.Person;@28a418fc
.
Si desea imprimir los nombres de las personas, hay muchas formas.
Podrías escribir tu propia función que itera cada persona e imprime
System.out.println(Arrays.toString(persons));
System.out.println(Arrays.deepToString(persons)); // for nested arrays
Puede imprimirlo usando Arrays.toString (). Esto me parece lo más simple.
Arrays.stream(persons).forEach(System.out::println);
Puede imprimirlo de la manera Java 8 (usando secuencias y referencia de método).
/**
* 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);
}
}
Puede haber otras formas también. Espero que esto ayude. :)
Si imprime directamente cualquier objeto de persona, será
ClassName@HashCode
en el código.
en su caso, se imprime
com.foo.Person@2f92e0f4
.
Donde
Person
es una clase a la que pertenece el objeto y
2f92e0f4
es el código hash del Objeto.
public class Person {
private String name;
public Person(String name){
this.name = name;
}
// getter/setter omitted
@override
public String toString(){
return name;
}
}
Ahora, si intenta usar el objeto de
Person
, se imprimirá el nombre
Class Test
{
public static void main(String... args){
Person obj = new Person("YourName");
System.out.println(obj.toString());
}
}
Si observa la clase Object (clase padre de todas las clases en Java), la implementación del método toString () es
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
cada vez que imprima cualquier objeto en Java, se llamará a toString (). Ahora depende de usted si anula toString (), entonces su método llamará a otra llamada al método de la clase Object.
Arrays.deepToString(arrayOfObject)
La función anterior imprime la matriz de objetos de diferentes primitivas.
[[AAAAA, BBBBB], [6, 12], [2003-04-01 00:00:00.0, 2003-10-01 00:00:00.0], [2003-09-30 00:00:00.0, 2004-03-31 00:00:00.0], [Interim, Interim], [2003-09-30, 2004-03-31]];