A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 昝文萌 中级黑马   /  2013-8-28 11:29  /  1958 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 昝文萌 于 2013-8-28 16:46 编辑

随着对java学习的越来越深入,发现有些习以为常的现象很值得思考。一开始学习java时就有关于System.out.priintln()的疑问,这个函数可以把字符串作为参数传进去然后打印在屏幕上,这是理所当然,但是它为什么还可传int类型的变量和其他基本数据类型。字符串是个对象,它打印字符串时可以把字符串的内容打印出来,但是打自定义对象时却是只打印地址值,同时对象打印的结果就不同,在调用这个函数时,到底发生了什么。
通过思考和验证发现调用System.out.priintln()打印对象时,实际上对象有调用了重写后的Object类的toString()方法!
  1. class Person
  2. {
  3.         private String name;
  4.         private int age;
  5.         Person(String name,int age)
  6.         {
  7.                 this.name = name;
  8.                 this.age = age;
  9.         }
  10.                 //重写toString方法
  11.         public String toString()
  12.         {
  13.                 return (name+age);
  14.         }
  15. }
  16. class Demo
  17. {
  18.         public static void main(String[] args)
  19.         {
  20.         
  21.                 Person p = new Person("li",21);
  22.                 System.out.println("p1="+p);//打印的不是地址值而是重写后的toString方法的内容
  23.                 System.out.println("p2="+p.toString());//结果和上面一样!
  24.                
  25.         }
  26. }
复制代码
如果没有重写自定义对象的toString方法,打印时调用父类Object的toString()方法打印名称和地址值。在自定义对象里重写了toString()后打印的是toString()的String类型的返回值!
由于String类,Interger类不能被继承,所以没法验证!
猜想:
1、System.out.priintln()方法只能打印String对象,打印其他对象时会调用对象父类Object的toString()方法返回的String对象。
2.打印String对象时也是调用该对象重写父类Object的toSting()方法。
3.打印像int这样的基本数据类型时,例如System.out.priintln(4),先把int类型进行装箱操作变为Tnterger对象,然后调用Interger对象的toString方法!
不知道这样的猜想是否合理。

评分

参与人数 1技术分 +1 收起 理由
黄兴旺 + 1

查看全部评分

2 个回复

正序浏览
本帖最后由 老衲玩IT 于 2013-8-28 14:23 编辑

toString()方法继承自Object,目的是方便输出对象的信息,sun公司编写的源码估计是这样
  1.         system.out.println(Object p){
  2.                 println(p.toString());
  3.         }
复制代码
说白了,println会通过类的多态特性调用p对象的toString方法

评分

参与人数 1技术分 +1 收起 理由
张智文 + 1 祝你早早赚够技术分

查看全部评分

回复 使用道具 举报
gulup 来自手机 中级黑马 2013-8-28 13:31:16
沙发
楼主的理解有一定的道理,我不敢说不对,但的确有点差别。print方法,不管传入什么参数都能输出,其实看API可以发现,System类~out,其实是一个System类里面定义的一个静态常量,这个常量是PrintStream类实例化对象。再去看 PrintStream的方法,可以看到,其实里面的print方法,经过了重写,8种基本数据类型都重写了一次,至于楼主说,方法内部是做了包装类的转换,我觉得应该不是,首先,要输出基本数据类型的话,还要转换成包装类,这就肯定会从一定的程度上加大了系统开销,我觉得方法内部应该是直接做了输出处理的,具体需要看源码。我不确定。手机没办法看源码。。。再来说String,这个在 PrintStream里面 也重写了一个输出String的方法。我觉得应该不应该是单单调用了,toString方法的,因为 PrintStream类里面还有一个重写过的print方法,里面的形参就是Object的,如果String也仅仅是调用了toString的话,就没必要特意为了String重写一个方法了吧?我觉得println(String s)这个方法,内部应该是直接查找并输出字符串常量池里面的字符的。具体还是要看源码。。下面的是println(int i)这个方法的说明。  Prints an integer and then terminate the line. This method behaves as though it invokes print(int) and then println().

评分

参与人数 1技术分 +1 收起 理由
张智文 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马