日期:2014-05-20  浏览次数:20827 次

华为面试第一题就把我整晕了!!
public   class   TestString{
    public   static   void   link(String   a){
            a   +=   "World ";
      }
    public   static   void   main(String[]   args){
            String   a   =   "Hello ";
            link(a);
            System.out.println(a);
    }
}
打印出来的结果是好多人想得不一样,即使一样很多人的思路也是错的(也就是瞎猜的)
      请指点!!!!!!!

------解决方案--------------------
特殊在String是不可变的
实参a和形参a是不同的引用,一开始都指向 "Hello "的地址,但是方法link改变了形参a所引用的地址内容,所以形参a指向新的 "Helloworld "的地址,但是 "Hello "仍然还在(String是不可变的,不会改变原来的 "Hello "为 "HelloWorld ",如果改变只会重新申请内存空间保留原来的内存空间)
所以方法调用结束后,实参a引用所指向的地址的内容没变,仍然为 "Hello "

------解决方案--------------------
首先要解决术语的问题,最适合“按值传递”的看起来是自变量。“按值传递”以及它的含义取决于如何理
解程序的运行方式。最常见的意思是获得要传递的任何东西的一个本地副本,但这里真正的问题是如何看待
自己准备传递的东西。对于“按值传递”的含义,目前存在两种存在明显区别的见解:
(1) Java 按值传递任何东西。若将基本数据类型传递进入一个方法,会明确得到基本数据类型的一个副本。
但若将一个句柄传递进入方法,得到的是句柄的副本。所以人们认为“一切”都按值传递。当然,这种说法
也有一个前提:句柄肯定也会被传递。但Java 的设计方案似乎有些超前,允许我们忽略(大多数时候)自己
处理的是一个句柄。也就是说,它允许我们将句柄假想成“对象”,因为在发出方法调用时,系统会自动照
管两者间的差异。
(2) Java 主要按值传递(无自变量),但对象却是按引用传递的。得到这个结论的前提是句柄只是对象的一
个“别名”,所以不考虑传递句柄的问题,而是直接指出“我准备传递对象”。由于将其传递进入一个方法
时没有获得对象的一个本地副本,所以对象显然不是按值传递的。Sun 公司似乎在某种程度上支持这一见
解,因为它“保留但未实现”的关键字之一便是byvalue(按值)。但没人知道那个关键字什么时候可以发
挥作用。
------解决方案--------------------
其实上面已经有人解释了。
唉,今天不睡觉了,再解释解释,其实也不是我说的,我是听侯捷说的,其实也不是侯捷说的,他也是翻译过来的(要是多写点文字能赚稿费就好了:)。
对于这个程序,
public class TestInteger{
public static void change(Integer i) {
i = new Integer(2);
}

public static void main(String[] args){
Iteger i = new Integer(1);
change(i);
System.out.println(i);
}
}

//////////////////////////////////////////////////
Iteger i = new Integer(1);
change(i);

i是指向Integer(1)的一个引用,change(i)执行的时候,并没有将i这个引用传进去,而是讲i这个引用的一个copy传进去了,可以看作执行了change(icopy),i和icopy指向同一个对象。在change函数里实际上是给icopy重新赋了值,但是i指向的那个对象并没有改变,只是icopy指向的对象变了。如果这么解释的话,还可以解释另外一个问题。就是下面的这个例子,如果不允性能得出正确答案,说明你过关了。大概changeObjectPart这个函数的原理和StringBuffer的appand差不多吧,哈哈。

/**
* @author wdman
*
*/
public class TestObject {

/**
* @param args
*/
public static void main(String[] args) {
TestObject to = new TestObject();
MyData myData = to.new MyData( "Hello ", "World! ");
System.out.println(myData);
to.changeObject(myData);
System.out.println(myData);
to.changeObjectPart(myData);
System.out.println(myData);
}

public void changeObject(MyData myData) {
myData = new MyData( "Hello ", "Money! ");
}

public void changeObjectPart(MyData myData) {
myData.s1 = "Hello ";
myData.s2 = "Girl! ";
}

class MyData {
public String s1;
public String s2;
public MyData(String s1,String s2) {
this.s1 = s1;
this.s2 = s2;
}

public String toString() {
return s1 + s2;
}
}
}