Java中参数传递是值传递,还是引用传递的一次深究
2011-11-06 12:02
691 查看
Java中参数传递是值传递,还是引用传递的一次深究
是我自己分析的,可能不准确,请大牛们指导,欢迎大家拍砖
1 先回顾一下java基础内容:对象在内存分配方式
这一句"Person p = new Person();" 分配了两个对象.
一个是引用对象p分配在栈中,
一个是实体对象new Person(),分配在堆上
并且p保存了实体对象的地址
如下图所示
栈内存 堆内存
引用对象p指向了 一个实体对象 Person.
对于堆上和栈上分配内存的释放,有java基础的人都知道,在这里就不说了。不知道可以百度。
2 函数中参数传递的两种类型
2.1 参数类型为基本类型 如 int float 等等
基本类型传递举例
相信大家都知道结果:
100
100
从这里,我们都可以看出java中方法的参数传递是按值传递的。
2.2 参数类型为对象类型 如Person
例子一
输出结果:
传递前age=10
传递后age=20
可能有人会想 例子一这里传递的是对象的引用。
例子二
输出结果
传递前age=10
传递后age=10
可能有人会想 例子二中这里传递的是对象的引用的一个复制。
对于例子二我想了一个图示
对于第二种参数传入类型为对象的情况,解释有3种
说法1 参数是按引用传递的,对于说法1 还有两种解释,
解释1 引用传递时是传入对象的引用
解释2 引用传递时是传入对象引用的复制
说法2 参数是按值传递
到底关于对象类型的参数,java中是按什么传递的,
其实java中不管是对象参数还是基本类型参数,都是按值传递的。
我们可以对方法中参数某些值进行打印 比如 Hashcode
这是部分代码 Person类可以参考上面定义的。
输出结果
传递前hascode=29855319
传递后hascode=29855319
我们可以看出 参数中传递进来的对象的hashcode和参数外面的一样。
我们再看一个例子
输出结果
比较对象结果:true
用==进行比较, 我们一直都认为是比较的值相等,而不是内容。
查看JDK文档中队 hashcode方法的描述,有这么一段话
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。
这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
通过上面的分析,关于对象传递,传递的是对象的一个引用(这里的引用跟c++中的引用不是一回事),这里的引用对象
是"该对象的内部地址转换成一个整数" ,其实就是一个整数。
所以我们可以肯定了java中不管是对象参数还是基本类型参数,都是按值传递的。
附带说明:
c++里面关于对象的一些知识
c++也是面向对象的语言,c++里面建立对象的方法是 :Person * p1 = new Person;
new出来返回的是一个对象的指针,java中没有指针这个说法。
而这个栈上的指针p也是指向堆上的new Person对象。
貌似跟java很类似,的确很类似 如果你在c++中也实现类似的改变Person中age的方法
他也改变 Person中age的值。他传入的是一个指针类型,从这个角度可以看出,C++中传递是按值传递的。
C++中按引用传递的方式是这样的
是我自己分析的,可能不准确,请大牛们指导,欢迎大家拍砖
1 先回顾一下java基础内容:对象在内存分配方式
public static void main(String[] args) { Person p = new Person(); }
这一句"Person p = new Person();" 分配了两个对象.
一个是引用对象p分配在栈中,
一个是实体对象new Person(),分配在堆上
并且p保存了实体对象的地址
如下图所示
栈内存 堆内存
引用对象p指向了 一个实体对象 Person.
对于堆上和栈上分配内存的释放,有java基础的人都知道,在这里就不说了。不知道可以百度。
2 函数中参数传递的两种类型
2.1 参数类型为基本类型 如 int float 等等
基本类型传递举例
public class PersonDemo { public static void main(String[] args) { int n =100; System.out.println(n); changeN(n); System.out.println(n); } public static int changeN(int a) { return a = a+1; } }
相信大家都知道结果:
100
100
从这里,我们都可以看出java中方法的参数传递是按值传递的。
2.2 参数类型为对象类型 如Person
例子一
public class PersonDemo { public static void main(String[] args) { Person p = new Person(); p.age = 10; System.out.println("传递前age=" +p.age); changeAge(p); System.out.println("传递后age=" +p.age); } public static int changeN(int a) { return a = a+1; } public static void changeAge(Person per) { per.age += 10; } } class Person { int age; }
输出结果:
传递前age=10
传递后age=20
可能有人会想 例子一这里传递的是对象的引用。
例子二
public class PersonDemo { public static void main(String[] args) { Person p = new Person(); p.age = 10; System.out.println("传递前age=" +p.age); changePerson(p); System.out.println("传递后age=" +p.age); } public static int changeN(int a) { return a = a+1; } public static void changeAge(Person per) { per.age += 10; } public static void changePerson(Person per) { Person p1 = new Person(); p1.age = 50; per =p1; } } class Person { int age; }
输出结果
传递前age=10
传递后age=10
可能有人会想 例子二中这里传递的是对象的引用的一个复制。
对于例子二我想了一个图示
对于第二种参数传入类型为对象的情况,解释有3种
说法1 参数是按引用传递的,对于说法1 还有两种解释,
解释1 引用传递时是传入对象的引用
解释2 引用传递时是传入对象引用的复制
说法2 参数是按值传递
到底关于对象类型的参数,java中是按什么传递的,
其实java中不管是对象参数还是基本类型参数,都是按值传递的。
我们可以对方法中参数某些值进行打印 比如 Hashcode
这是部分代码 Person类可以参考上面定义的。
public class PersonDemo { public static void main(String[] args) { Person p = new Person(); System.out.println("传递前hascode=" +p.hashCode()); hc(p); } public static void hc(Person per) { System.out.println("传递后hascode=" +per.hashCode()); } }
输出结果
传递前hascode=29855319
传递后hascode=29855319
我们可以看出 参数中传递进来的对象的hashcode和参数外面的一样。
我们再看一个例子
public class PersonDemo { static Person CP = new Person(); public static void main(String[] args) { equalPer(CP); } public static void equalPer(Person per) { System.out.println("比较对象结果:" +(per == CP)); } }
输出结果
比较对象结果:true
用==进行比较, 我们一直都认为是比较的值相等,而不是内容。
查看JDK文档中队 hashcode方法的描述,有这么一段话
实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。
这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
通过上面的分析,关于对象传递,传递的是对象的一个引用(这里的引用跟c++中的引用不是一回事),这里的引用对象
是"该对象的内部地址转换成一个整数" ,其实就是一个整数。
所以我们可以肯定了java中不管是对象参数还是基本类型参数,都是按值传递的。
附带说明:
c++里面关于对象的一些知识
c++也是面向对象的语言,c++里面建立对象的方法是 :Person * p1 = new Person;
new出来返回的是一个对象的指针,java中没有指针这个说法。
而这个栈上的指针p也是指向堆上的new Person对象。
貌似跟java很类似,的确很类似 如果你在c++中也实现类似的改变Person中age的方法
public void changeAge(Person * p) { p->age += 10; }
他也改变 Person中age的值。他传入的是一个指针类型,从这个角度可以看出,C++中传递是按值传递的。
C++中按引用传递的方式是这样的
public void changeAge(Person & p) { p.age += 10; }
相关文章推荐
- java参数传递(值传递还是引用传递)
- java参数传递(值传递还是引用传递)
- Java中参数传递是值传递,还是引用传递
- 【Java基础】基本类型的包装类作为参数传递是值传递还是引用传递
- java参数传递(值传递还是引用传递)
- java参数传递(值传递还是引用传递)
- java中方法的参数传递机制(值传递还是引用传递)
- java参数传递(值传递还是引用传递)
- java参数传递(值传递还是引用传递)
- java参数传递(值传递还是引用传递)
- Java 参数传递(到底是值传递 还是引用传递)
- Java中向方法传递的参数是引用还是值?
- java值传递还是引用传递
- Java:按值传递还是按引用传递详细解说
- JAVA中参数传递问题的总结(按值传递和引用传递)
- Java的方法的参数传递,值传递和引用传递还有String字符串传递
- Java:按值传递还是按引用传递详细解说
- Java-String 到底是值传递还是引用传递
- 【Stackoverflow好问题】Java是按值传递还是按引用传递
- Java到底是值传递还是引用传递?