Java基本类型和对象类型 传值

关于java中只有“值传递”的认识:如果是基本类型就传递值的拷贝(基本类型的包装类型),如果是对象类型就传递引用的拷贝(所以根据传递的引用能够改变原有对象的值,但是不能重新指向另外的对象,否则不会改变

传递值的拷贝:基本类型(int char float double等),基本类型的包装类型(IntegerFloatDouble等); 按理说,包装类型也是对象,根据传递引用应该可以该百年对象的值,但实际中确实不能改变。

package com.zgd;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int a = 1;
		testInt(a);
		System.out.println("a="+a);//
		
		Integer b = new Integer(1);
		testInteger(b);
		System.out.println("b="+b);//1
		
		Integer c= new Integer(1);
		testNewInteger(c);
		System.out.println("c="+c); //1
		
	}
	
	static void testInt(int a){
		a = 2;			
	}
	
	static void testInteger(Integer b){
		b = 3;			
	}
	
	static void testNewInteger(Integer c){
		c = new Integer(4);			
	}
}
传递引用的拷贝:内部定义对象(如数组)和自定义对象

package com.zgd;

import java.util.Arrays;

public class A {
	public static void main(String[] args) {
		int[] aa = { 3, 2, 1 };
		System.out.println(Arrays.toString(aa)); // [3, 2, 1]
		test(aa);
		System.out.println(Arrays.toString(aa)); // [3, 2, 1]
		test2(aa);
		System.out.println(Arrays.toString(aa)); // [4, 2, 1]
	}

	static void test(int[] a) {
		a = new int[] { 1, 2, 3 }; // 指向了新对象
	}

	static void test2(int[] a) {
		if (a != null && a.length > 0)
			a[0]++; // 修改原来的那个对象
	}
}
但是关于String类型的传递有些问题:

按前面的分析,String属于对象类型,当String作为参数传递的是引用,应该可以改变其内部类型,但实际中却并没有改变。 但换成StringBuff却可以!

package com.zgd;

public class Test2 {
	public static void test(String str) {
		str=str.concat("zgd");
		System.out.println("inner:"+str);//Hellozgd
	}

	public static void main(String[] args) {
		String string = "Hello";
		test(string);
		System.out.println(string);//Hello
		
	}
}


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

关于String的问题在这篇博客中给来分析,博主分析源码认为String是char[]的包装类型,所以和Integer一样不能改变。

很可惜这样的分析是错误的,首先char[]作为数组传递(java中数组被认为是对象)是可以修改其值的。这里的根本问题是因为String中的char[]是final的,也就是不可改变的,那么当String进行修改,比如 str=str.concat("zgd"); 这里实际上等价于 str = new String(str.concat("zgd"));

这就是问题的关键:test方法中str作为对象类型传递引用,str是string(“hello”)的引用,但是当str = new String(str.concat("zgd"));之后str便有了自己新的内存,不再指向原来的的string(“hello”)。当从方法中返回的时候,这个临时复制的引用str被销毁,但是string(“hello”)中的内容仍然没有改变。为了更清楚地解释,请看下面的StringBuffer例子

换成StringBuffer

package com.zgd;

class MyDemo {  
	  
    public static void operate(StringBuffer x, StringBuffer y) {  
        x.append(y);  
        y = x;  
        System.out.println(x + "," + y);//AB,AB
        x = new StringBuffer("A"); //指向来新的空间,不再和原来的StringBuffer a有任何关系
        System.out.println(x + "," + y);//A,AB
    }  
  
    public static void main(String[] args) {  
        StringBuffer a = new StringBuffer("A");  
        StringBuffer b = new StringBuffer("B");  
        operate(a, b);  
        System.out.println(a + "," + b); //AB,B 
    }  
}  
这里需要特别注意的是operate方法中x.append(y)改变了a对象,但是
x = new StringBuffer("A"); 
却没有改变对象。这是为什么??? 因为x指向了重新分配的内存空间“A”

总结:(1)正确理解java中只有“值传递”的:如果是基本类型就传递值的拷贝(基本类型的包装类型),如果是对象类型就传递引用的拷贝(所以根据传递的引用能够改变原有对象的值,但是不能重新指向另外的对象,否则不会改变

(2)基本类型和基本类型的包装类型是值拷贝的传递;对象类型是引用拷贝的传递

(3)引用拷贝一定不能指向重新分配的内存,因为指向来新的内存是改变不了原来对象的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值