Java值传递

     

      首先声明一点,在Java 编程语言只有值传递参数,而没有引用传递。

      昨天有人给我讲java中的值传递和引用传递,理所当然的我就说基本类型是引用传递,对象类型的是引用传递,那个人还问了好多次,你确定么,我坚定的回答,肯定是这样的。
     后来写了几个demo,才发现以前对这些基本知识都没有深刻的认识。如果这是一次面试,听了这样的回答,面试官会果断的不要我。


     在这之前先讲一个基本知识点,java中有 ==和equals两个比较方法,大概的意思是==比较的是两个对象的地址,即句柄,equals继承了Object类,比较的是两个对象的内容。对象有一个hashCode()的方法,其实是对其进行hash,具体的算法不说,大概的意思就是取其物理地址。


     首先先暂时不考虑基本类型,和C++中一样基本类型是值传递,方法传递的是一份拷贝,不会修改真实值。接着要讲的是对象类型。

      下面来看几个神奇的demo:

      1、

	public static void main(String[] args) {
		String str = "old";
		System.out.println(str);
		change(str);
		System.out.println(str);
	}
	public static void change(String str){
		str = "newString";
	}
       当我认为运行结果理所当然的是

       old

       newString         的时候

      正确的运行结果却是:

      old

      old


      原因可以这样理解,其实change方法中给传递的是对象引用的拷贝,但是俩指向的都是同一个对象,但是上面的change方法,把引用的拷贝指向了一个新的对象“newString”,而真实的依然是指向“old”这个对象,因此主函数中调用方法以后对象值仍然不变。

      

    再来看一个demo2:

	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder("old");
		System.out.println(sb.toString());
		System.out.println(sb.hashCode());
		change2(sb);
		System.out.println(sb.toString());
		System.out.println(sb.hashCode());
	}
	public static void change2(StringBuilder sb){
		sb = new StringBuilder("New String");
		sb.append("append");
		System.out.println(sb.toString()); 
		System.out.println(sb.hashCode());
	}
执行结果如下:

old
1396452035
New Stringappend
320574182
old
1396452035


demo3代码以及运行结果如下:

	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder("old");
		System.out.println(sb.toString());
		System.out.println(sb.hashCode());
		change2(sb);
		System.out.println(sb.toString());
		System.out.println(sb.hashCode());
	}
	public static void change2(StringBuilder sb){
		sb.append("append");
		System.out.println(sb.toString()); 
		System.out.println(sb.hashCode());
	}


old
1441188650
oldappend
1441188650
oldappend
1441188650
     由上两个代码可以得出,由于传递的对象的引用的拷贝和对象的引用指向的是同一对象,当对对象的值进行操作的时候,真实的引用指向的对象也会改变。但是当拷贝指向新的对象以后,原来的引用指向的对象依旧是原来的那个不会改变。

    


另外额外再补充一点:

String类是一个非常特殊的类:

String类是不可变的,对String类的任何改变,都是返回一个新的String类对象,因此尽管你对String的值进行了改变,但事实上是返回了一个新的对象。

比如下面的一段代码,可以看到str的真实值没有改变,因为String的subString方法返回的也是一个新的字符串对象。

	public static void main(String[] args) {
		String str = "idontknow";
		System.out.println(str);
		change1(str);
		System.out.println(str);
	}
	public static void change3(String str){
		str = str.substring(2,str.length());
		System.out.println(str); 
	}
	
idontknow
ontknow
idontknow

值得注意的是当使用
String str="abc"+"de";
这样一段代码的时候,由于String的对象是一个常量,会放到String常量池中,因此会占用资源,所以,经常会使用StringBuffer来构建字符串然后再将其转化成String.




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值