关于JAVA的值传递和引用传递&String

来源:互联网 发布:网络理财诈骗案 编辑:程序博客网 时间:2024/05/01 16:58

今天看了几个案列,感觉无比的压力。。。最基础的问题竟然分不清楚- -

然后各种尝试,各种捅度娘,爆google,整理了一下各路大神的观点和案列,让自己更好的理解下java的值传递和引用传递


先是统一简单的定义一下

值传递:是对所传递参数进行一次副本拷贝,对参数的修改只是对副本的修改,函数调用结束,副本丢弃,原来的变量不变(即实参不变)

引用传递:参数被传递到函数时,不复制副本,而是直接将参数自身传入到函数,函数内对参数的任何改变都将反映到原来的变量上。

这里我选的案列比较多,用于比较

先是基本数据类型和对象的比较

classDemo
 {
     
int a;
     
public   Demo(int  a)
     {
         
this.a=a;
     }
  }
 
public classTestQuote{
     
public static voidmain(String args[])
   { Demo d1
=newDemo(1);  
     Demo d2
=newDemo(2); 
     System.out.println(d1.a);
     System.out.println(d2.a);  }
     function(d1,d2);
     System.out.println(d1.a);
     System.out.println(d2.a);
   }
     
private static voidfunction(Demo d1,Demo d2)
     {
               int a;
              a
=d1.a;
              d1.a
=d2.a;
              d2.a
=a;
     }
}
调用function()函数以前输出的结果是12,调用后是2,1,这是引用传递的一个“说法”。

pubilc class Test {

    public statci void change(int i ,int j)

    {    int temp = i;

         i = j;

         j = temp;

    }

    public static void main(String[] args)

    {   int a =3, b = 4;

        System.out.println("before change a:"+a+"and"+" "+"b"+b);

        change(a,b);

        System.out.println("after change a:"+a+"and"+" "+"b"+b);

    }

 }

这里的结果永远都是 3,4,当然有些会把打印语句放在chage中,表示这些基本

类型的数据确实在方法内调用换位了,但是在主函数中,依旧没变。


通过以上案列,我们至少可以从结果上来很好的区分值传递和引用传递了,但是还远没玩啊~~~


这里,就不得不提一个特殊的类,String,要不是它,我根本不会写这个文章了。。。二话不说,先看案列(转载自某百度空间)

我这里把类名和方法略作简写,方便阅读

public class StringDemo {

        public staticvoid main(String[] args) {

             StringDemo sd =    new StringDemo();

             sd.testA(); 


        }

        private void testA() {

             String originalStr = "original";

             System.out.println("Test A Begin:");  

             System.out.println("The outer String: " + originalStr);

             ChangeString(originalStr);

             System.out.println("The outer String after inner change: " + originalStr);

             System.out.println("Test A End.");

             System.out.println();

        } //这里多次输出,用来更好表现程序执行过程

        public void ChangeString(String original) {

             original = original + " is changed!";

             System.out.println("The changed inner String: " + original); 


        }

}
 
以上代码是先赋值一个String类型的局部变量,然后把这个变量作为参数送进一个方法中,在这个方法中改变该变量的值。

其结果是

Test A Begin:
The outer String: original
The changed inner String: original is changed!
The outer String after inner change: original
Test A End.
即,在方法内部对String类型的变量的重新赋值操作并没有对这个变量的原型产生任何影响。

我们已经知道值传递就是无论该参数在方法内怎样被改变,外部的变量原型总是不变

若是引用传递,则 方法改变参数变量的同时变量原型也会随之改变。(stringbuffer就是)

问题至此而来,我看的毕老师的视频中,明确强调String str = "adsf";这new了一个对象,说明String不是一个基本数据类型

既然不是基本数据类型,那就应该不是值传递啊?很多人喜欢用String这个类来描述java的值传递和引用传递,起初看的我是雨里雾里啊。。。

先不慌,理理思绪,看案例继续

这里给个小插曲,关于String str = "adsf"和String str =new String("adsf"); 的区别

String str = "adsf"是把字符串存储在类的常量池中,而new出来的是放在堆内存中,比较普遍的说法是创建了2个对象,一个adsf,一个str的引用;

我认为引用是引用,对象是对象,不是一个概念,自己要分清,当然要是有,我是说假如有人面试或者问,就说一个是对象,一个是引用,别说2个对象。。。

然后回到Sring的传递问题,这其实和它的底层有关,详情API

 public String(String original) {

                int size = original.count;

                char[] originalValue = original.value;

                char[] v;

                if (originalValue.length > size) {

                        // The array representing the String is bigger than the new

                        // String itself.    Perhaps this constructor is being called

                        // in order to trim the baggage, so make a copy of the array.

                            int off = original.offset;

                            v = Arrays.copyOfRange(originalValue, off, off+size);

                } else {

                        // The array representing the String is the same

                        // size as the String, so no point in making a copy.

                        v = originalValue;

                }

                this.offset = 0;

                this.count = size;

                this.value = v;

}

String的存储实际上通过char[]来实现的,也就是说和IntegerFloat啊,一样,是基础类型的包装类

而且是char类型的包装类,故为什么String是值传递的原因就在此。



好了,差不错玩了,本来还想写,回头看看,最重要的写完了,继续回到视频去~(今天真是花了不少时间啊~~,累~)







原创粉丝点击