Java,关于ToString方法调用的一道题 求高手帮忙看看

BUG写手樱桃老爷爷 2019-03-14 09:14:58
作为一名合格的BUG写手,前两天好容易休息日,翻QQ。
意外刷到10年前老同学的QQ相册。才发现原来也是同行。
少不了一顿寒暄得知原来他在某学校做老师。还顺便扔了一题给我看看。
原题如下:

不运行代码,直接说出打印结果,并解释原因。
public class ToStringTest{
static inti= 1;
public static void main(String args[]){
System.out.println("love " + new ToStringTest());
ToStringTest a = new ToStringTest();
a.i++;
System.out.println("me " + a.i);
}
public String toString(){
System.out.print("I ");
return "java ";
}
}


第一遍读题我也是萌比的,觉得这位同学就是故意想绕晕我。于是我放弃攻题,直接单步运行,先看结果。
但不过程中 运行语句上窜下跳,先看看运行结果:
I I I I love java
I I I me 2

看到这结果,我认为其中必有蹊跷。
于是直接完整运行了一次。
结果如下:
I love java
me 2

这样的结果才像样嘛,嗯。

这个时候我已经被绕进去了。
就想弄清楚这当中的运行顺序。
于是对原题进行了大量增删改同时观察报错情况。
最后整理出一下结论。
希望路过的大佬能帮我看看。这当中有没有总结的对的地方···
菜鸟真心求专业解答。本来不喜欢研究这些钻牛角尖的问题。
但是既然做出了总结,就很担心自己的总结是错的,反而中了那个同学的下怀被他给坑了。。。

以下:
public class ToStringTest{
/* static int i= 1;*/ //排除不重要的干扰因素
public static void main(String args[]){
Object a = new ToStringTest();// 此处创建了 多态对象 因为 ToStringTest 对象相加会直接报错
Object b = new ToStringTest();// 暂且可以当做 和原题中 创建匿名对象 的效果相似
String c = "love ";
if (a!="1"+a){ // 这当中 每增加一个 加号 结果中就多一个 I
if(a!=a+"1"+a+a){ // 这当中 不能让对象相加 优先于 对象与字符串 或 字符串与对象 拼接
b= a+/*c="love "*/c+a; // 否则 也会报错 比如 “a+a+“1”” 或 “1+(a+a)” 都不行
}
}
System.out.println( b/*new ToStringTest()*/); // 从结果上来看 a+ 和 +a 都相当于 "java "
/* a.i++;
System.out.println("me " + a.i);*/ // 排除不重要的干扰因素
}
public String toString(){ // 这里重写了 toString 的方法 是本次研究的关键
System.out.print("I "); // 每次调用 toString 方法 都会 打印 一个 “I ”
return "java "; // *** toString 方法中的的 (参数对象) 会被当做"java "用来拼接
} // *** obj对象+ 或 +obj对象 都会调用toString 方法
} // *** obj对象+ 或 +obj对象 会被toString 的返回值代替 然后和字符串拼接
// *** obj对象之间不能先与 拼接 而进行 +运算

求专业解答

...全文
208 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 3 楼 lumen12 的回复:
引用 1 楼 qybao 的回复:
obj对象+或+obj对象会调用toString是不对的,那是因为跟String对象相加,系统自动把obj转成String,所以才会调用toString方法,你可以试试跟别的类型相加,编译就报类型错误。你直接a+a为什么会报错,原因就在这里。
我想说的就是这个意思 可能表达的有问题
我就是想表达 所谓的系统自动转换 就是在调用tostring 而直接a+a肯定是不行的
  • 打赏
  • 举报
回复
引用 2 楼 大隐藏于寺 的回复:
为了方便描述,我重新贴一下代码
public class ToStringTest{
    static inti= 1;
    public static void main(String args[]){
        System.out.println("love " + new ToStringTest()); 
        ToStringTest a = new ToStringTest();
        a.i++;
        System.out.println("me " + a.i); 
    }
    public String toString(){
        System.out.print("I "); 
        return "java ";
    }
}
我不太清楚楼主开发工具是否是使用的IntelliJ IDEA.我使用的IntelliJ IDEA 2018.3.3,在单步调试时复现了楼主的结果. 我在代码的第4行和第10行打的断点. 我的控制台输出为:
I I I love java 
I I me 2
I 
如果楼主是想问IntelliJ IDEA的单步调试时为什么会打印出这个结果,而不是与直接执行结果一致.那么答案是IntelliJ IDEA的一个默认设置导致这一结果.File | Settings | Build, Execution, Deployment | Debugger | Data Views | Java |Enable toString() object view 关闭后再单步调试,控制台输出:
I love java 
me 2
参考: 1.https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000622624--skipped-breakpoint-at-because-it-happened-inside-debugger-evaluation-; 2.https://youtrack.jetbrains.com/issue/IDEA-178509#comment=27-2426329
我是个菜鸟 想表的只是楼上说的那个问题..您说的这个问题我只是观察到了 深入研究就算了吧 感觉对我来说太难了 我用的也是08.3.3
  • 打赏
  • 举报
回复
引用 1 楼 qybao 的回复:
obj对象+或+obj对象会调用toString是不对的,那是因为跟String对象相加,系统自动把obj转成String,所以才会调用toString方法,你可以试试跟别的类型相加,编译就报类型错误。你直接a+a为什么会报错,原因就在这里。
我想说的就是这个意思 可能表达的有问题
stacksoverflow 2019-03-15
  • 打赏
  • 举报
回复
你想得太复杂了。 首先非单步的运行结果没什么好解释的(对象和字符串进行拼接的时候会调用对象的toString()方法把对象变成字符串), 对于单步运行的结果,我猜: 你在debug的时候会有个显示变量的地方,比如变量a 你鼠标点变量a的时候,要输出给a的值给你看吧,这时候a是对象的话就会调用一下toString, 所以没什么好奇怪的,是工具的问题,和java运行时无关,不必深究。
  • 打赏
  • 举报
回复
我不认同这种看法哦 那个老同给我的答案就是new调用了重载过的方法 然而这正是我觉得需要纠结一番的地方. 因为 没多一次拼接操作就会多出一个I 而和 new多少次实例无关
ToughPZG 2019-03-15
  • 打赏
  • 举报
回复
我觉得楼主没必要想着么复杂吧,第一个打印,是因为new 了一个对象,在控制台打印需要先调用tostring方法,所以打印 I,而后才执行打印 love java.
大隐藏于寺 2019-03-14
  • 打赏
  • 举报
回复
为了方便描述,我重新贴一下代码
public class ToStringTest{
    static inti= 1;
    public static void main(String args[]){
        System.out.println("love " + new ToStringTest()); 
        ToStringTest a = new ToStringTest();
        a.i++;
        System.out.println("me " + a.i); 
    }
    public String toString(){
        System.out.print("I "); 
        return "java ";
    }
}
我不太清楚楼主开发工具是否是使用的IntelliJ IDEA.我使用的IntelliJ IDEA 2018.3.3,在单步调试时复现了楼主的结果. 我在代码的第4行和第10行打的断点. 我的控制台输出为:
I I I love java 
I I me 2
I 
如果楼主是想问IntelliJ IDEA的单步调试时为什么会打印出这个结果,而不是与直接执行结果一致.那么答案是IntelliJ IDEA的一个默认设置导致这一结果.File | Settings | Build, Execution, Deployment | Debugger | Data Views | Java |Enable toString() object view 关闭后再单步调试,控制台输出:
I love java 
me 2
参考: 1.https://intellij-support.jetbrains.com/hc/en-us/community/posts/115000622624--skipped-breakpoint-at-because-it-happened-inside-debugger-evaluation-; 2.https://youtrack.jetbrains.com/issue/IDEA-178509#comment=27-2426329
qybao 2019-03-14
  • 打赏
  • 举报
回复
obj对象+或+obj对象会调用toString是不对的,那是因为跟String对象相加,系统自动把obj转成String,所以才会调用toString方法,你可以试试跟别的类型相加,编译就报类型错误。你直接a+a为什么会报错,原因就在这里。

50,556

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧