主要是关于基本数据类型和引用数据类型的问题,大家请看题目:public class Test
{
public void change(String str,char[] c,StringBuffer buffer1,StringBuffer buffer2)
{
str+="world";
c[2]='d';
buffer1.append("AAA");
buffer2=new StringBuffer("BBB");
}

/**
 * @param args
 */
public static void main(String[] args)
{
Test t=new Test();

String str="hello";
char[] c={'a','b','c'};
StringBuffer buffer1=new StringBuffer("aaa");
StringBuffer buffer2=new StringBuffer("bbb");

t.change(str, c, buffer1,buffer2);

System.out.println(str);
System.out.println(c[2]);
System.out.println(buffer1);
System.out.println(buffer2);
}
}

解决方案 »

  1.   

    额,这样,也不用去运行了大家,直接看答案吧
    hello
    d
    aaaAAA
    bbb
    话说我虽然有那么一点点的理解,但是基本上还是不懂的。所以,大家懂了
      

  2.   

    这个例子比较好的阐释了java是值传递的,对象作为参数时,可以改变对象的属性,但不可改变对象的内存地址,String是final 型的,你可以把它当做基本类型一样用
      

  3.   

    LZ先理解好什么是变量,什么是对象
    再理解好方法的栈以及变量的内存空间和对象的内存空间的关系
    这个问题就本就迎刃而解了public class Test
    {
        public void change(String str,char[] c,StringBuffer buffer1,StringBuffer buffer2)
        {
           //LZ想想看,这个str是什么,是变量还是对象?"word"又是什么,它和main的str又是什么关系?
            str+="world";  //这个是改变变量的指向,让变量指向新的对象,但不影响main的str的指向  
            c[2]='d'; //这个是改变变量指向的对象的属性,所以main的c也能知道对象的属性改变了   
            buffer1.append("AAA"); //这个也是改变变量指向的对象的属性
            buffer2=new StringBuffer("BBB"); //这个是改变变量的指向,让变量指向新的对象
        }
        
        /**
         * @param args
         */
        public static void main(String[] args)
        {
            Test t=new Test();
            
            String str="hello";        
            char[] c={'a','b','c'};
            StringBuffer buffer1=new StringBuffer("aaa");
            StringBuffer buffer2=new StringBuffer("bbb");
            
            t.change(str, c, buffer1,buffer2);
            
            System.out.println(str);
            System.out.println(c[2]);
            System.out.println(buffer1);
            System.out.println(buffer2);
        }
    }
    打个比方,LZ你是main的buffer1,我是change的buffer1,我们是两个同的地方的人(就相当于两个buffer1是两个不同的变量),我和你一起浏览这个页面,就相当于两个buffer1一起指向同一个对象,那么我和你看到的内容是一样的,如果我在这里留下一段文字,也就是我调用append方法,你也能看到这段文字,因为我们看的是同一个页面,而我是修改这个页面的属性,追加了一段文字,而你也在看这个页面(相当于你也指向这个对象),所以你能看到我做出的任何修改,而如果我调用buffer1=xxx,相当于我去看别的页面了,但你在看这个页面(也就是main的buffer1指向没有改变),那么我在别的页面做的修改,LZ你还能看到吗?因为你我看的不是同一个页面,你怎么能知道修改的信息呢?同样的道理,change的buffer2指向了新的对象,它作出的修改,main的buffer2又怎么能知道呢?所以要理解好变量和对象的区别与联系。也就是打比方这个例子中的你和我和页面的关系要理解清楚。
      

  4.   

    你学过c/c++把 其实就是
    指针传递问题 + String不变对象概念
    指针传递就是值传递(区别与引用传递)-其实就是传地址 1.java中String是不变的就是说 new出来后不能直接修改其内部数据.只能生成新的对象.
    str+="world" //生成了新的对象,但是main中还是指向原来的对象
    c[2]='d'; //java中其实数组就是一个对象 而且main传递的也是指针
    buffer1.append("AAA"); //对象内部数据被改变
    buffer2=new StringBuffer("BBB"); //对象内部数据被改变其实可以详细看一下 scjp的教材开头对参数传递的描述.
    java的引用 其实从表面上可以看作指针
      

  5.   

    首先,我得感谢为我解答这道题目的哥哥也好,叔叔也好,总之,我要对你们说声谢谢了!像这类问题我困惑了好久好久了,一直对这类问题搞的糊里糊涂,本来看这个帖子过了一天两天都没多少人回,心里很失望,于是我逛了论坛别的地方,发现了一个很好的帖子,关于堆与栈的
    http://http://topic.csdn.net/u/20081123/12/f70f1632-24be-4caa-bc20-29cf8267afab.html?93144今晚突然发现了8楼和9楼的回复,很感动,csdn还是有很多好心人的特别8楼的讲解,在结合我看到的那篇帖子,我想面试的时候遇到这种问题我会迎刃而解吧。再次感谢CSDN的大神们
      

  6.   

    突然发现连接没用!我重新发试试http://topic.csdn.net/u/20081123/12/f70f1632-24be-4caa-bc20-29cf8267afab.html?93144
      

  7.   

      这个问题的本质就是java数据类型的底层实现与final关键字的问题.  java在方法调用是,所有的参数都是copy一份出来,将copy后的数据做参数,调用方法。
      比如 private void test(int a){..}
           public void test1(){ int i = 0 ; test(i);};在运行调用test方法时,栈中会存放两个为0的整数,一  个是i,一个用于调用test方法。 java中对象,数组调用时也是如此,不同的是对象,数组存放在栈中不是它原有的值而是一个地址,这就是人们说的地址引用.这是因为java会将对象,数组存放在堆内存当中,当运行时就只会给一个堆的地址引用。
      比如 privatevoid test(User user){
                user.setName("aaaa");
    }  
     public void test1(){
            User uesr = new User();
              test(user);
    }
     初始话user时,在栈中不是存放的user对象,而是在堆中初始化一个对象,并将对象的地址引用给了栈中的user。 假设堆中的地址为"123", 这是,栈中user对应的就是“123”这个地址,当调用test时,会在栈中产生两个user出来,但是他们都对应"123"这个地址,因此修改一个。另一个也会被修改掉.但是重新给他一个地址引用,以前的的数据不会被修改,这就是StringBuffer出现的情况. 另外一种情况,就是final关键字的使用,String 对象在JDK中使用final修饰,也就代表它不能被修改,只能被复制,因此java在实现的时候,实际是在堆中New了一个string出来,你可以简单的认为buffer2的过程,只不过它是有JVM实现。
     
      

  8.   

    各位大哥大姐,帮我分析一个小小的问题啊,我刚注册发帖的资格都没有、也没积分不好意思啊。
    题目: public static void main(String[] args)
    {
    short a = 3;
    a = a + 4;(错) a = (short) (a + 4);// (a = a + 4;错误)
    a += 4;
    我想问: a+ 4制动转换为int了这个我知道,但是a += 4;不知道为什么可以通过编译?
      我找过一些相关问题资料有的说:
    short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 
    对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。
    对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译
     
    想请问一下怎么特殊处理啊??求解。为了这个小问题纠结了几天了,说重要也不重要,但是我很郁闷啊
      

  9.   

    这样的问题不用纠结那么多,就是编译器遇到 += 这样的处理的时候就帮你自动转换了
    怎么特殊处理,就是 把 += 自动变为 value = (xxx)(value + data)来编译
    就好像一些封装类 Integer i = 5 自动变为 Integer i = Integer.valueOf(5) 来编译一样
      

  10.   

    都是传引用只是String类,很特别。 已经提醒过很多次哦,String类长度是固定的str+="world";    
    //你认为是字符串变长了,但是实际上str已经变成了新的引用地址了
    //而原来地址的值并没有改变所以这和传值与传引用无关。 只是你没有理解String类而已