Java值传递,引用传递相关知识

本文借鉴优秀文章:http://blog.sina.com.cn/s/blog_5ef745830100giyq.html

   http://blog.sina.com.cn/s/blog_7fb1495b01012sfn.html

  http://blog.csdn.net/unagain/article/details/774039

  http://freej.blog.51cto.com/235241/168676     


一、java中的基本数据类型和引用数据类型

java中的数据类型分为两大类:基本数据类型和引用数据类型

基本数据类型(8种),包括数值型,字符型和布尔型。

数值型:1)整型:byte 1个字节;short 2个字节;int 4个字节;long 8个字节。

        2)浮点型:float 4个字节;double 8个字节;可以采用十进制和十六进制两种表示方式,其中十六进制表示方法只能采用科学计数法,例如:0x1.2p3,表示的是的是1乘以16加上2乘以16的-1次方的和乘以2的三次方;浮点型的默认类型为DOUBLE型,如果声明float型浮点数,要在数值后面加上f或F,例如:float f1 = 3.14F;否则会报精度错误。

3)字符型:char 采用unicod的16位编码方式进行编码。

4)布尔型:true,false;

 

引用数据类型:类、接口类型、数组类型、枚举类型、注解类型;

 

二、基本数据类型和引用数据类型的区别主要在存储方式上:

  基本数据类型在被创建时,在栈上给其划分一块内存,将数值直接存储在栈上;

  引用数据类型在被床架时,首先要在栈上给其引用(句柄)分配一块内存,而对象的具体信息都存储在堆内存上,然后由栈上面的引用指向堆中对象的地址。

  例如:我有一个类MyDate,其中有属性day,mouth,year等,有构造方法(带参数);

       现在为其创建一个对象MyDate d1 = new MyDate(8,8,2008);

在内存中的具体创建过程是:

 1)首先在栈内存中位其d1分配一块空间;

2)然后在堆内存中为MyDate对象分配一块空间,并为其三个属性设初值0,0,0;

3)根据类MyDate中对属性的定义,为该对象的三个属性进行赋值操作;

4)调用构造方法,为三个属性赋值为8,8,2008;(注意这个时候d1与MyDate对象之间还没有建立联系)

5)将MyDate对象在堆内存中的地址,赋值给栈中的d1;通过句柄d1可以找到堆中对象的具体信息。


三、按值传递和按引用传递的区别

说明:
    (1)、“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。

    (2)、在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义的字符串方式:String str = "Java快车";

    (3)、运行第11行,是把mian方法中的变量a所引用的内存地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。实参,形参的变量都是a变量,但是内存地址是不同的。形参新开辟一个内存临时存储。

    
    java中的引用类型概念


四、Java-String类型的参数传递问题

也许你注意到了里面的 char[], 这说明对 String 的存储实际上通过 char[] 来实现的。怎么样?其实就是一层窗户纸。不知道大家还记不记得在 Java API 中定义的那些基本类型的包装类。比如 Integer int 包装类、 Float float 的包装类等等。对这些包装类的值操作实际上都是通过对其对应的基本类型操作而实现的。是不是有所感悟了?对, String 就相当于是 char[] 的包装类。包装类的特质之一就是在对其值进行操作时会体现出其对应的基本类型的性质。在参数传递时,包装类就是如此体现的。所以,对于 String 在这种情况下的展现结果的解释就自然而然得出了。同样的, Integer Float 等这些包装类和 String 在这种情况下的表现是相同的,具体的分析在这里就省略了,有兴趣的朋友可以自己做做试验。
这也就是为什么当对字符串的操作在通过不同方法来实现的时候,推荐大家使用 StringBuffer 的真正原因了。至于 StringBuffer 为什么不会表现出 String 这种现象,大家再看看的 StringBuffer 的实现就会明白了,在此也不再赘述了。


你可能感兴趣的:(java,形参,实参,值传递,引用传递)