(基本数据类型值+对象)参数传递方式+对象的引用和拷贝
2013-02-06 15:39
471 查看
1.Java参数传递方式
网络上有很多地方都说明java的参数传递方式是值传递,虽然其最终的解释是正确的。但我认为值传递定义为java参数传递方式并不妥。可以分成两种,便于记忆和理解:1.基本数据类型的值传递 2.对象的引用传递(传址)。
当然这里会有一个问题基本数据类型只能值传递么?如何进行引用传递?
待以后慢慢研究吧
下面用直接用代码来说明一下这两种参数传递方式的区别:
// 基本数据类型是值传递,而非引用传递 public void changeInt(int params) { params = params * 2 + 1; } // java对象是引用传递而非引用传递 public void changeObject(A a) { a.a = "hello 2013!"; } @Test public void changeTest() { int i = 3; CloneTest ct = new CloneTest(); ct.changeInt(i); A a = new A(); a.a = "style!"; ct.changeObject(a); System.out.println(i);//结果 3 System.out.println(a.a);//结果 hello 2013! }
---------------------2013年5月2日---------------------------------------------------------
这里需要纠正之前的认识,java的传递只有一种就是值传递。
public void changeList(List<Integer> list){ List<Integer> tlist=new ArrayList<Integer>(); tlist.add(1); tlist.add(2); list=tlist; } @org.junit.Test public void testList(){ List<Integer> l =new ArrayList<Integer>(); changeList(l); System.out.println(l.size());//0 }
我们可以改变赋值对象的内容,但对已对象的赋值是没有任何意义的。因此参数不应该被赋值超过两次。
在参数前加final关键字。
2.对象的拷贝
1.浅拷贝和深拷贝
接下来的问题便是,如果我不想改变原来对象的属性内容,但又想得到对象的属性内容咋办?简言之,如何拷贝对象。网上有很多地方都提到拷贝会产生风险,其实我们应该能理解,因为引用时无时无刻都存在的,但凡是对象,所以我们在处理拷贝时一定要非常注意。
那这里就会涉及到浅拷贝和深拷贝两个概念。
2.如何拷贝(对自定义类的对象)
在使用中我们经常要对自定义类的对象进行拷贝,因为自定义类中可以包含其他自定义类对象变量,基本数据类型变量或者jdk提供的其他类型的变量(集合,数组等等),而我们的任务便是将这些属性值进行拷贝。
先来看一下一个最简单的拷贝对象的例子:
Modification Log: package com.techbirds.lang; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; public class CloneTest { @Test public void cloneTest1() throws CloneNotSupportedException { C c1 = new C(); c1.c = "c1"; C c2 = new C(); c2 = (C) c1.clone(); System.out.println(c1.c);//c1 System.out.println(c2.c);//c1 System.out.println(c1==c2);//false System.out.println(c1.c==c2.c);//true c2.c = "c2"; System.out.println(c1.c);//c1 System.out.println(c2.c);//c2 System.out.println(c1.c==c2.c);//false } } /** * 实现Cloneable接口,实现浅拷贝 * */ class C implements Cloneable { public String c; /* * (non-Javadoc) * * @see java.lang.Object#clone() */ @Override protected Object clone() throws CloneNotSupportedException { C o = null; try { o = (C) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } }这个例子对于深浅拷贝做了很好的解释,很明显对于拷贝过来的对象中,对于属性c我们只对其进行了浅层拷贝。
那问题就抛向我们:那如何对类变量进行深层拷贝呢?其实很简单:对类变量所在类v也必须进行克隆实现。
@Test public void testObject1() throws CloneNotSupportedException{ D d1=new D(); d1.d="12"; String[] strs1=new String[]{"1","2"}; d1.ds=strs1; List<String> l1=new ArrayList<String>(); l1.add("12"); d1.lds=l1; A a=new A(); a.a="a"; d1.a=a; D d2=(D) d1.clone(); System.out.println(d1==d2);//false System.out.println(d1.a.hashCode()+":"+d2.a.hashCode());//20324370:7578443 System.out.println(d1.ds.hashCode()+":"+d2.ds.hashCode());//31822120:31822120 }
class A implements Cloneable{ public String a; /* (non-Javadoc) * @see java.lang.Object#clone() */ @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class D implements Cloneable{ public List<String> lds; public String[] ds; public String d; A a; /* (non-Javadoc) * @see java.lang.Object#clone() */ @Override protected Object clone() throws CloneNotSupportedException { D o = null; try { o = (D) super.clone(); a=(A) o.a.clone();//如果这句话没有-浅层拷贝,有-深层拷贝 } catch (CloneNotSupportedException e) { e.printStackTrace(); } return o; } }
相关文章推荐
- 由【JAVA中参数传递问题】引发除了基本数据类型和引用类型的思考
- java 传递参数 “引用是一种数据类型”,“参数是引用的一个拷贝”
- 基本数据类型和引用数据类型参数传递图解
- 基本数据类型参数传递图解引用数据类型参数传递图解
- Js从头学起(基本数据类型和引用类型的参数传递详细分析)
- java中传递参数的两种方式(int(基本类型),int[](对象类型))
- 基本数据类型与引用数据类型参数传递
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- Js从头学起(详细分析基本数据类型和引用类型的参数传递)
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- 基本数据类型值传递和引用数据类型值传递比较
- 基本数据类型和引用数据类型当做参数传递
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- 基本数据类型参数传递与引用数据类型参数传递区别
- JS基本数据类型和引用类型的参数传递详细分析
- [javase学习笔记]-6.6 基本数据类型参数与引用数据类型参数的传递过程
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- 基本数据类型的包装类型作为参数传递,以及其他引用类型作为参数传递,以及List中值的交换的一些问题
- Java中方法调用参数传递的方式是传值,尽管传的是引用的值而不是对象的值。(Does Java pass by reference or pass by value?)