1.前几日同学发来了一道Java面试题,觉得挺有意思,于是决定写下个人的理解。
题目是这样的: 需要在method方法被调用之后,仅打印出a=100,b=200 请写出method方法
package jdk.lang;
public class SystemIOE {
public static void main(String[] args) {
int a = 10;
int b = 10;
Method(a, b);
/*
* 需要在method方法被调用之后,仅打印出a=100,b=200 请写出method方法
*/
}
private static void Method(int a, int b) {
// TODO Auto-generated method stub
// write your code
}
}
2.你会怎么答
如果你这么答的话,
private static void Method(int a, int b) {
// TODO Auto-generated method stub
// write your code
a = a * 10;
b = b * 20;
}
说明你对参数传递理解得不够透彻。
参数传递主要有:
i.按值传递参数
按值传递参数时,是将实参变量的值复制一个到临时存储单元中,如果在调用过程中改变了形参的值,不会影响实参变量本身,即实参变量保持调用前的值不变。
ii.按地址传递参数
按地址传递参数时,把实参变量的地址传送给被调用过程,形参和实参共用内存的同一地址。在被调用过程中,形参的值一旦改变,相应实参的值也跟着改变。如果实参是一个常数或表达式,Visual Basic 6.0会按”传值”方式来处理,按地址传递不需要”ByVal”关键字。
而题目中用到的是按值传递参数
3.正确的答案
i.重写PrintStream对象的println()方法,然后重新设置系统的标准输出流对象。
private static void Method(int a, int b) {
// TODO Auto-generated method stub
// write your code
PrintStream printStream = new PrintStream(System.out) {
public void println(String x) {
if ("a=10".equals(x)) {
x = "a=100";
} else {
x = "b=200";
}
super.println(x);
};
};
System.setOut(printStream);
}
ii.在method方法中输出a=100,b=200,然后终止虚拟机
private static void Method(int a, int b) {
// TODO Auto-generated method stub
// write your code
System.out.println("a=100");
System.out.println("b=200");
System.exit(1);
}
4.原理解析
i.首先method方法一定是静态的,因为Main方法也是静态的。在静态方法中被调用的方法也必须是静态的。
ii.下面是第一种答案:
a).我们先来看看system类,在此类中有标准的输入输出流。
b)与这题相关的是out对象,out即标准输出流对象。
这个对象被PrintStream包装的实例对象,通过这个对象我们可以往控制台输出所有我们想要输出的信息。
诸如:
package jdk.lang;
import java.io.PrintStream;
public class SystemIOE {
public static void main(String[] args) {
PrintStream printStream = new PrintStream(System.out);
printStream.println("hello");
printStream.flush();
}
}
输出:hello
所以当我们复写了PrintStream的println之后,然后再重新设置系统(System.setOut(printStream);)的输出流对象的时候即可符合题目的要求。
iii.第二种答案
就是在输出a=100,b=200之后直接终止了Java虚拟机,所以也满足了题目要求。
System.exit(1);