java参数传递的最终理解
来源:互联网 发布:东方不败网络歌手 编辑:程序博客网 时间:2024/05/29 05:54
java的参数传递一直是个令初学者搞不懂的知识(- - 比如我)。今天决下心来敲代码,研究透彻java的参数传递。
根据所学习的资料,java的参数传递只有一种——值传递。
可能大部分CS专业的学生(再次——比如我)最初都是由接触C/C++开始,因此印象中总会有两种参数传递类型——1.值传递,2.引用传递。
再说说两种传递类型(浅谈C/C++):
1.值传递——值传递时内存会将原来的数据拷贝一份,将拷贝的作为参数进行传递,因此在其他地方对该参数所做的修改并不会影响原来的数据。
2.引用传递——引用传递是将原来数据的地址(java中为引用)直接作为参数进行传递,因此在其他地方对该参数所做的修改相当于修改原数据。
说到这里,就要说说java的特点了——引用,java与C++不同,无指针,java的数据类型分为两种,基本类型和引用类型。但从设计思想的本质看是一样的,都是point的感觉。
java的这个特性很容易使初学者认为java的参数传递就是“引用传递",但其实不是。
举个例子,
<span style="font-size:14px;"> Exp exp = new Exp();</span>new Exp()实例化一个对象,而exp = new Exp();就让exp引用向这个对象,exp在内存开辟的栈中储存实例化对象的地址。当将exp进行参数传递时,值传递的机制在内存栈区创建了一个栈帧,储存的是exp这个引用的拷贝引用,因此传递后刚才的对象变成了两个引用,在栈中,exp和拷贝值储存相同的地址。
下面我直接就以代码来展开吧~
public class TestCall {
<span style="font-size:14px;"> //类成员-------------------------------</span><pre name="code" class="java"><span style="font-size:14px;"> Book bb = new Book("数据结构", 20); Book aa = new Book("操作系统", 40); Book cc = new Book("改变后1", 20); Book dd = new Book("改变后2", 40); Book[] book={aa,bb}; Book[] book1 ={cc,dd};</span>
<span style="font-size:14px;"> //内部类------------------------------public class Book{ private String name; private double price; public Book(String name, double price) { this.name = name; this.price = price; } public void setPrice(double p) { this.price = p; } //覆盖------------------------------- @Override public String toString() { return "[name=" + this.name + ", price=" + this.price + "]"; } } //更改对象内容------------------------------ void adjustPrice(Book aBook) { //aBook.setPrice(100.0); //---改变了--- aBook = new Book("我改了书名",30);//---不改变--- } void changePrice(Book[] book){ //book[1] = new Book("这次是数组,我改了书名",30);//---改变了--- book[1].setPrice(100.0);//---改变了--- //book = book1;//---不变--- //book[1] = book1[1];//---改变--- } //更改基本类型内容------------------------------ void adjustBase(int a){ a = 3; } void changeBase(int[] a){ a[1] = 3; }}</span>
这里我将main方法抽取出来便于编写。
(1)
<span style="font-size:14px;"> public static void main(String[] args){TestCall t = new TestCall();//对象------具体数组元素做参数---------------------System.out.println("前: "+t.book[1]);t.adjustPrice(t.book[1]);//具体数组元素做参数System.out.println("后: "+t.book[1]);System.out.println("");}</span>
运行结果:
前: [name=数据结构, price=20.0]
后: [name=数据结构, price=20.0]
结论:可以看到,原数据没有收到影响。
(2)
<span style="font-size:14px;">//对象------直接用对象做参数System.out.println("前: "+t.bb);t.adjustPrice(t.bb);System.out.println("后: "+t.bb);System.out.println("");</span>
运行结果:
前: [name=数据结构, price=20.0]
后: [name=数据结构, price=20.0]
用图解释下:
(3)
<span style="font-size:14px;">//对象数组--------------------------System.out.println("前: "+t.book[1]);t.changePrice(t.book);//整个数组的引用做参数System.out.println("后: "+t.book[1]);System.out.println("");</span>
运行结果:
前: [name=数据结构, price=20.0]后: [name=数据结构, price=100.0]
结论: 将数组作为参数传递时,发生了改变。
理解: 数组对象实际上也是引用,值传递后内存栈出现两个引用向实例化数组的对象,但book[i]会操作到原对象进而改变原数据。
再加深理解, 若将类成员方法changePrice(Book[])的方法体改为book = book1;
运行结果是:
前: [name=数据结构, price=20.0]
后: [name=数据结构, price=20.0]
可以看到,这次原数据没有发生改变,为什么呢? 其实就是我们将book引用向了另一个数组book1,操纵的不是源对象,因此原数据没有发生改变。
来到这里
让我们将(2)中的adjustPrice方法的方法体改为
aBook.setPrice(100.0);再运行看看结果:
前: [name=数据结构, price=20.0]
后: [name=数据结构, price=100.0]
结论: 我们惊奇地发现,原来的数据居然变了,其实道理也就和上面一样——因为我们操纵了源对象。
bb对象和值传递时的拷贝值都引用向原来的实例,但aBook.setPrice操纵了源对象,即它们共同引用的对象,因此原数据改变了
用图片来解释下:
(4)
//基本类型-------------------------int a=1;System.out.println("a是: "+a);t.adjustBase(a);System.out.println("a是: "+a);System.out.println("");
运行结果:
a是: 1
a是: 1
结论:与单个具体对象一样,不会影响原数据
(5)
//基本类型数组-------------------------int[] aa={1,2,3,4};System.out.println("aa[1]是: "+aa[1]);t.changeBase(aa);System.out.println("aa[1]是: "+aa[1]);
aa[1]是: 2
aa[1]是: 3
结论:原来数组的值发生了改变,原理如(3)
总结一下:1、本质上,当传递参数为对象时,只要对参数的操作不是对原对象的操作就不会改变原数据的值。
2、当传递参数为基本数据类型时,不会对原数据造成任何影响。
但这里需要强调的是: 若传递的是数组对象(无论是基本类型数据还是对象)而不是具体的单个数组元素,则对传递数据的操作相当于对原数据的操作,即会改变原数据。
- java参数传递的最终理解
- 理解JAVA里的所有参数传递都是值传递
- JAVA中函数调用参数传递的理解(值传递和引用传递的理解)
- 关于JAVA 参数传递理解
- 深入理解Java参数传递
- Java:理解Java中函数参数传递的【按值传递】和【按引用传递】
- 理解EJB的参数传递
- 理解EJB的参数传递
- 函数参数传递的理解!
- 深入理解Java方法调用的参数传递
- 对于Java中函数参数传递的理解
- 对Java方法参数按值传递的理解
- 关于java中参数传递的简单理解
- 深入理解Java中方法的参数传递机制
- 对Java方法参数按值传递的理解
- 关于java中参数传递的理解和总结
- Java参数传递造成参数值改变的情况--值传递和引用传递的初步理解
- Java参数传递造成参数值改变的情况--值传递和引用传递的初步理解
- php连接mssql数据库的几种方式
- python set
- IPython下的网络协议学习-------以echo回显程序为例
- ORACLE逻辑操作符
- PHP PDO函数库详解
- java参数传递的最终理解
- jQuery和AngularJS的区别
- 集群的设计思路和常用的技术
- Hydra工具解析
- Android Studio 下获取开发版应用(application)的SHA1---方法之一
- 浅谈C++多态性
- session失效时间设置
- php使用PDO方法详解
- 原生javascript-图片滚动按需加载