在java中打印对象时会发生什么
class Data { int a = 5; } class Main { public static void main(String[] args) { int b=5; data dObj = new data(); System.out.println(dObj); System.out.println(b); } }
我想知道在打印对象或数字或字符串时发生了什么。
我运行上面的代码,我得到的结果为System.out.println(dObj);
“data @ 1ae73783” System.out.println(dObj);
System.out.println(b);
“5” System.out.println(b);
然后我做了调试来检查打印对象时真的发生了什么,在调试模式中调用了很多参数(比如classloader,theards)
我知道第一次打印时,值表示类名后跟地址。 但是不知道在调试模式下真正发生了什么,因为在调试模式中发生了第二次打印变量赋值,即b = 5。
请解释一下真的发生了什么?
您不需要调试器就能知道发生了什么。 System.out的类型为PrintStream。 PrintStream.println(Object)的javadoc说:
打印一个对象,然后终止该行。 此方法首先调用String.valueOf(x)来获取打印对象的字符串值,然后表现为调用print(String)然后调用println()。
String.valueOf(Object)的javadoc说:
如果参数为null,则字符串等于“null”; 否则,返回obj.toString()的值。
而Object.toString()的javadoc说:
返回对象的字符串表示forms。 通常,toString方法返回一个“文本表示”此对象的字符串。 结果应该是简洁但信息丰富的表示,便于人们阅读。 建议所有子类都覆盖此方法。
类Object的toString方法返回一个字符串,该字符串由对象为实例的类的名称,符号字符“@”以及对象的哈希码的无符号hex表示组成。 换句话说,此方法返回一个等于值的字符串:
getClass().getName() + '@' + Integer.toHexString(hashCode())
请解释一下真的发生了什么?
正如其他人告诉你的那样,将System.out.println
与对象一起使用将调用该对象上的toString
方法。 如果类没有自己的toString
方法,那么它是对超类的toString
的调用。 如果超类调用一直返回java.lang.Object
,则默认的toString
方法打印对象类型的名称(它是什么类),后跟@
符号,以及对象的内存位置 -该对象存储在内存中的hex地址。
ClassName@MemoryLocation
所有对象都inheritance自java.lang.Object,其默认实现为toString。 如果一个对象覆盖了这个方法,那么out.print(obj)会在屏幕上放置一些有用的东西。
原始数据类型由println的不同,更简单的实现来处理。 除了Object之外,还会为每种数据类型重写println方法。
首先, int
不是Object
。 这是原始类型。 其次,当Class没有超过toString()
方法时,调用来自Object类的toString()
。
数据dObj =源代码中不存在新数据(); 如果要打印对象的字符串值(Data),则必须覆盖toString方法;
试试这个
public class Program { public static void main(String[] args) { Data data = new Data(); System.out.println(data); } } class Data { int a = 5; @Override public String toString() { return String.valueOf(a); } }