这是我们公司的面试问题,自招募第二个Java以来就一直存在。 但是,经过这么长时间的面试都没有人能答对,所以我们一度认为这道题是错的。 请先看面试问题。
以下运算的输出分别是多少:
publicstaticvoidmain (字符串[ ]数组) {
int i=0;
变更(I;
系统输出打印机(I;
}
私有身份交换(英寸2 ) {
i2=1;
}公共建筑(字符串[ ]数组)
整数I=0;
变更(I;
系统输出打印机(I;
}
私有资产交换(集成电路2 ) {
i2=1;
}公共建筑(字符串[ ]数组)
stringbuilder s=新stringbuilder ('0);
变更(s;
系统输出打印机(s;
}
私有建筑变更(stringbuilder S2 ) {
S2=新字符串生成器('1);
读完问题后,你已经有自己的答案了吗? 记录下你的答案,如果不介意的话在评论区留言,看看有人是否完全正确。
首先需要明确几个概念。
参加形式:
如下图所示,格式参数是在定义函数名称和函数主体时使用的参数,其目的是接收在调用该函数时传递的参数。
实际的参数是在调用带有参数的函数时传递的参数。
堆和堆栈:
堆栈存储基本类型的变量数据和对对象的引用,但对象本身不存储在堆栈中,而是存储在堆(从new中出来的对象)或常量池中。 字符串常量对象存储在常量池中。 )
存储从new中出来的所有对象。
常量池存储字符串常量和基本类型常量。
传递值和引用传递:
必须明确只将值传递给Java。 传递值和引用,传递值而不是传递的内容,传递的是值,传递的是引用传递的参数既不是普通类型,也不是按值传递,而是对象或引用传递。 用第三个主题进行分析。 首先,让我们看看在程序运行过程中堆栈发生了什么。
如上图所示。
第一步是创建一个空间,将引用s存储在堆栈中,将对象存储在堆中。 值为0。 步骤2中的调用方法在堆栈中声明另一个引用s2,并指向步骤1中的对象地址。 如果在步骤3中更改s2的值,实际上会向堆中添加新的空间,s2将指向新的地址。 由上图可见,s的指向没有改变。 因此,在第三个问题中得到的答案是0。
继续看第二个问题,第二个问题和第三个问题的区别是,因为Integer的值放在常量池中,所以上图的堆会变得和常量池中的其他完全一样,所以第二个问题的答案也会变成0。
关于第1个问题,由于所涉及的形式参与实参是基本型,因此I和i2完全由堆栈操作,此时打印的结果仍为0。