zoukankan      html  css  js  c++  java
  • Java基础之引用(String,char[],Integer)总结

    1、String的引用:

    下列代码执行后的结果为:

    [java] view plain copy
     
    1. public class Test {  
    2. public static void main(String[] args) {  
    3.     StringBuffer a = new StringBuffer("A");   
    4.     StringBuffer b = new StringBuffer("B");   
    5.     operator(a, b);   
    6.     System.out.println(a + "," + b);   
    7. }   
    8. public static void operator(StringBuffer x, StringBuffer y) {   
    9.     x.append(y); y = x;   
    10. }  
    11. }  


     

    正确答案是:AB,B

    解析:

        执行StringBuffer a = newStringBuffer("A");    StringBuffer b = newStringBuffer("B"); 后
    内存中的状态如下图所示:
     
    执行
    publicstaticvoidoperator(StringBuffer x, StringBuffer y) { 
        x.append(y); y = x; 
    }
    进入如下方法后,内存中的状态为:
     
     x.append(y);
    这条语句执行后,内存的状态为:
     
     y = x; 
    这条语句执行后,内存的状态为:
     
    当operator方法执行完毕后内存中的状态为:因为方法执行完毕,局部变量消除。
     
    由内存中的状态,可以知道最后的结果。
     
     
    可以这么理解:
     
         a,b是对象的引用,指向堆内存。将a,b两个引用传给x,y,执行x.append(y)方法之后改变了x 引用指向的堆内存的存储内容,变为了AB。y=x,表示引用y指向了引用x指向的存储区域,没有改变引用b指向的存储空间的内容。所以输出为:AB,B
     
     
     
     
     
     
    2、String和char数组引用的区别与联系:
     
     
    输出正确结果为:
    [java] view plain copy
     
    1. public class Example {  
    2.     String str = new String("good");  
    3.     char[] ch = { 'a', 'b', 'c' };  
    4.    
    5.     public static void main(String args[]) {  
    6.         Example ex = new Example();  
    7.         ex.change(ex.str, ex.ch);  
    8.         System.out.print(ex.str + " and ");  
    9.         System.out.print(ex.ch);  
    10.     }  
    11.    
    12.    public void change(String str, char ch[])        
    13.    {  
    14.         str = "test ok";  
    15.         ch[0] = 'g';  
    16.     }  
    17. }  
    输出为:good and gbc
     
    解答:
     
           概念:java传参只有按值传递(也就是把实参的值拷贝给形参,这个值可以是普通的数值,也可以是地址值),java中的对象只能通过指向它的引用来操作,这个引用本身也是变量,不要与C/C++中的传值与传址混淆了,java中没有显式的指针。

          分析:change函数被调用时,第一个形参str接收了类的成员变量str的值(虽然名称都是str,但是却是两个独立的String类型的引用变量),注意这两个str自身都是变量且都指向了堆内存中的String对象"good",当我们在change函数内部将str指向了另一个String对象"test ok"后,类的成员变量str仍然保持指向"good",所以最终打印出来就是"good";对于第二个形参ch,它也是接收了类的成员变量ch的值拷贝,这一点和str没有差别,即两个ch都指向了字符数组{ 'a', 'b', 'c' }的首地址,但是ch[0]表示的是字符数组中'a'的地址,修改了它也就修改了字符数组的第一个元素,这个改变在change函数返回之后也会存在。所以本题中两个形参传参的本质区别在于,修改str只是将形参指向了新的对象,对外部的实参没有任何影响,而修改ch[0]是实实在在的修改了字符数组的首元素。
        
         扩展:
    1.可以试验一下,在Example中再定义一个字符数组char[] ch2={'d'};然后在change函数中把ch[0] = 'g';这句改成ch=ch2;,那么就会和str传参一样的,change函数返回后不会对类的成员ch有任何影响。
    2.本题和“String类是一个final类,不能被继承”以及“String底层的字符数组被声明为private final char value[];所以其值不能被修改”这些String的特性无关。
     
    扩展代码:
    [java] view plain copy
     
    1. public class Example {  
    2.     String str = new String("good");  
    3.     char[] ch = { 'a', 'b', 'c' };  
    4.     char[] ch2={'d'};  
    5.    
    6.     public static void main(String args[]) {  
    7.         Example ex = new Example();  
    8.         ex.change(ex.str, ex.ch);  
    9.         System.out.print(ex.str + " and ");  
    10.         System.out.print(ex.ch);  
    11.     }  
    12.    
    13.    public void change(String str, char ch[])        
    14.    {  
    15.         str = "test ok";  
    16.         ch=ch2;  
    17.     }  
    18. }  

    输出为:good and abc
     
     
     
    3、关于Integer的引用案例:
     
     
    下列代码正确输出结果为:
    [java] view plain copy
     
    1. public class Tester{  
    2. public static void main(String[] args){  
    3.    Integer var1=new Integer(1);  
    4.    Integer var2=var1;  
    5.    doSomething(var2);  
    6.    System.out.print(var1.intValue());  
    7.    System.out.print(var1==var2);  
    8. }  
    9. public static void doSomething(Integer integer){  
    10.     integer=new Integer(2);  
    11.     }  
    12. }  

    正确答案为:1true
     
    解析:
    来看一张图,
     
    下边按照每行来写出注释:
    (1)新建了一个引用变量var,指向了堆内存中的1。
    (2)将引用变量var1复制给var2,使var2也指向了堆内存中的1。
    (3)调用doSomething方法,则新建了一个引用变量integer,也指向了堆内存中的1。
    (4)然后执行方法体内容,将integer指向了堆内存中的2。
     
    则输出必然为1true。
     
    可以看下扩展例子:
     
          当引用对象的内部做了修改,才会影响原对象,如果直接将引用修改了,则对原对象没有影响,唯一的影响就是:这个被修改的引用,现在不是原来对象的引用,而是新对象的引用。
          引用传递指的是传递的时候,传递的是对象的引用。如果对引用的内部成员进行操作,则会直接影响到原对象,但是如果直接把此引用指向了其他对象,那对不起,这个引用从此以后,便与之前的对象没有任何关系,当前代表的仅仅是新指向的对象。
  • 相关阅读:
    java并发系列(六)-----Java并发:volatile关键字解析(内存语义、实现原理)
    java并发系列(五)-----如何正确的关闭一个线程
    23.备忘录模式(Memento Pattern)
    22.访问者模式(Vistor Pattern)
    21.责任链模式
    20.策略者模式(Stragety Pattern)
    19.状态者模式(State Pattern)
    18.中介者模式(Mediator Pattern)
    17.观察者模式(Observer Pattern)
    16.迭代器模式(Iterator Pattern)
  • 原文地址:https://www.cnblogs.com/andy-alone/p/7231033.html
Copyright © 2011-2022 走看看