- 浏览: 720236 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (439)
- 生活小感 (9)
- Java (65)
- 笔面经 (18)
- 算法 (45)
- 读书笔记 (1)
- Android (147)
- 设计模式 (7)
- C语言 (7)
- 职业生涯 (6)
- 网络 (5)
- 数据库 (3)
- Linux/Unix (21)
- C++ (7)
- 思考 (3)
- WinPhone (4)
- Git (6)
- http (1)
- UML (1)
- SQL (2)
- Ant (1)
- iOS (14)
- FFmpeg (22)
- WebRTC (10)
- Mac (2)
- web (0)
- TCP (2)
- Vim (2)
- OpenSSL (1)
- OpenGL (6)
- 多媒体 (10)
- cocos2d (2)
- svn (1)
最新评论
-
wahahachuang8:
我觉得这种东西自己开发太麻烦了,就别自己捣鼓了,找个第三方,方 ...
WebSocket初探【转】 -
ding335306:
这个目录下没有找到此文件
eclipse.ini in MAC -
songshuaiyang:
哥们写东西可真乱啊
Android获取cpu和内存信息、网址的代码 -
zhoutao_temp:
这是自己能看懂还是让别人能看得懂,您就不能把版面稍微整理一下吗 ...
FFMPEG源码分析 -
chriszeng87:
string2020 写道git clone --bare表示 ...
复制git库
1. 简单类型是按值传递的
Java 方法的参数是简单类型的时候,是按值传递的 (pass by value)。这一点我们可以通过一个简单的例子来说明:
public class Test {
public static void test(boolean test)
{test = ! test;
System.out.println("In test(boolean) :
test = " + test);}
public static void main(String[] args)
{boolean test = true;
System.out.println("Before test(boolean) :
test = " + test);
test(test);
System.out.println("After test(boolean) :
test = " + test);}
}
运行结果:
Before test(boolean) : test = trueIn test(boolean) : test = falseAfter test(boolean) : test = true
不难看出,虽然在 test(boolean) 方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响,即对 main(String[]) 方法里的 test 变量没有影响。那说明,参数类型是简单类型的时候,是按值传递的。以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法函数的,那么在方法函数里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。
2. 什么是引用
Java 是传值还是传引用,问题主要出在对象的传递上,因为 Java 中简单类型没有引用。既然争论中提到了引用这个东西,为了搞清楚这个问题,我们必须要知道引用是什么。
简单的说,引用其实就像是一个对象的名字或者别名 (alias),一个对象在内存中会请求一块空间来保存数据,根据对象的大小,它可能需要占用的空间大小也不等。访问对象的时候,我们不会直接是访问对象在内存中的数据,而是通过引用去访问。引用也是一种数据类型,我们可以把它想象为类似 C 语言中指针的东西,它指示了对象在内存中的地址——只不过我们不能够观察到这个地址究竟是什么。
如果我们定义了不止一个引用指向同一个对象,那么这些引用是不相同的,因为引用也是一种数据类型,需要一定的内存空间来保存。但是它们的值是相同的,都指示同一个对象在内存的中位置。比如
String a = "Hello";String b = a;
这里,a 和 b 是不同的两个引用,我们使用了两个定义语句来定义它们。但它们的值是一样的,都指向同一个对象 "Hello"。也许你还觉得不够直观,因为 String 对象的值本身是不可更改的 (像 b = "World"; b = a; 这种情况不是改变了 "World" 这一对象的值,而是改变了它的引用 b 的值使之指向了另一个 String 对象 a)。那么我们用 StringBuffer 来举一个例子:
public class Test {public static void main(String[] args) {StringBuffer a = new StringBuffer("Hello");StringBuffer b = a;b.append(", World");System.out.println("a is " + a);}}运行结果:a is Hello, World
这个例子中 a 和 b 都是引用,当改变了 b 指示的对象的值的时候,从输出结果来看,a 所指示的对象的值也改变了。所以,a 和 b 都指向同一个对象即包含 "Hello" 的一个StringBuffer 对象。
这里我描述了两个要点:
1. 引用是一种数据类型,保存了对象在内存中的地址,这种类型即不是我们平时所说的简单数据类型也不是类实例(对象);
2. 不同的引用可能指向同一个对象,换句话说,一个对象可以有多个引用,即该类类型的变量。
3. 对象是如何传递的呢
关于对象的传递,有两种说法,即“它是按值传递的”和“它是按引用传递的”。这两种说法各有各的道理,但是它们都没有从本质上去分析,即致于产生了争论。既然现在我们已经知道了引用是什么东西,那么现在不妨来分析一下对象作是参数是如何传递的。还是先以一个程序为例:
public class Test {public static void test(StringBuffer str) {str.append(", World!");}public static void main(String[] args) {StringBuffer string = new StringBuffer("Hello");test(string);System.out.println(string);}}运行结果:Hello, World!
test(string) 调用了 test(StringBuffer) 方法,并将 string 作为参数传递了进去。这里 string 是一个引用,这一点是勿庸置疑的。前面提到,引用是一种数据类型,而且不是对象,所以它不可能按引用传递,所以它是按值传递的,它么它的值究竟是什么呢?是对象的地址。
由此可见,对象作为参数的时候是按值传递的,对吗?错!为什么错,让我们看另一个例子:
public class Test {public static void test(String str) {str = "World";}public static void main(String[] args) {String string = "Hello";test(string);System.out.println(string);}}运行结果:Hello
为什么会这样呢?因为参数 str 是一个引用,而且它与 string 是不同的引用,虽然它们都是同一个对象的引用。str = "World" 则改变了 str 的值,使之指向了另一个对象,然而 str指向的对象改变了,但它并没有对 "Hello" 造成任何影响,而且由于 string 和 str 是不同的引用,str 的改变也没有对 string 造成任何影响,结果就如例中所示。
其结果是推翻了参数按值传递的说法。那么,对象作为参数的时候是按引用传递的了?也错!因为上一个例子的确能够说明它是按值传递的。
结果,就像光到底是波还是粒子的问题一样,Java 方法的参数是按什么传递的问题,其答案就只能是:即是按值传递也是按引用传递,只是参照物不同,结果也就不同。
①单纯考虑参数str存的也是一种数据类型,可以看成是值传递。
②考虑参数str它是对象string的一个引用,此时就可看做是引用传递。
4. 正确看待传值还是传引用的问题
要正确的看待这个问题必须要搞清楚为什么会有这样一个问题。
实际上,问题来源于 C,而不是 Java。
C 语言中有一种数据类型叫做指针,于是将一个数据作为参数传递给某个函数的时候,就有两种方式:传值,或是传指针,它们的区别,可以用一个简单的例子说明:
void SwapValue(int a, int b) {int t = a;a = b;b = t;}void SwapPointer(int * a, int * b) {int t = * a;* a = * b;* b = t;}void main() {int a = 0, b = 1;printf("1 : a = %d, b = %d\n", a, b);SwapValue(a, b);printf("2 : a = %d, b = %d\n", a, b);SwapPointer(&a, &b);printf("3 : a = %d, b = %d\n", a, b);}运行结果:1 : a = 0, b = 12 : a = 0, b = 13 : a = 1, b = 0
大家可以明显的看到,按指针传递参数可以方便的修改通过参数传递进来的值,而按值传递就不行。
当 Java 成长起来的时候,许多的 C 程序员开始转向学习 Java,他们发现,使用类似SwapValue 的方法仍然不能改变通过参数传递进来的简单数据类型的值,但是如果是一个对象,则可能将其成员随意更改。于是他们觉得这很像是 C 语言中传值/传指针的问题。但是 Java 中没有指针,那么这个问题就演变成了传值/传引用的问题。可惜将这个问题放在 Java 中进行讨论并不恰当。
讨论这样一个问题的最终目的只是为了搞清楚何种情况才能在方法函数中方便的更改参数的值并使之长期有效。
Java 中,改变参数的值有两种情况,第一种,使用赋值号“=”直接进行赋值使其改变,如例 1 和例 4;第二种,对于某些对象的引用,通过一定途径对其成员数据进行改变,如例 3.对于第一种情况,其改变不会影响到方法该方法以外的数据,或者直接说源数据。而第二种方法,则相反,会影响到源数据——因为引用指示的对象没有变,对其成员数据进行改变则实质上是改变的该对象。
转自考试大 http://www.examda.com/Java/jichu/20090508/092721753.html
Java 方法的参数是简单类型的时候,是按值传递的 (pass by value)。这一点我们可以通过一个简单的例子来说明:
public class Test {
public static void test(boolean test)
{test = ! test;
System.out.println("In test(boolean) :
test = " + test);}
public static void main(String[] args)
{boolean test = true;
System.out.println("Before test(boolean) :
test = " + test);
test(test);
System.out.println("After test(boolean) :
test = " + test);}
}
运行结果:
Before test(boolean) : test = trueIn test(boolean) : test = falseAfter test(boolean) : test = true
不难看出,虽然在 test(boolean) 方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响,即对 main(String[]) 方法里的 test 变量没有影响。那说明,参数类型是简单类型的时候,是按值传递的。以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法函数的,那么在方法函数里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。
2. 什么是引用
Java 是传值还是传引用,问题主要出在对象的传递上,因为 Java 中简单类型没有引用。既然争论中提到了引用这个东西,为了搞清楚这个问题,我们必须要知道引用是什么。
简单的说,引用其实就像是一个对象的名字或者别名 (alias),一个对象在内存中会请求一块空间来保存数据,根据对象的大小,它可能需要占用的空间大小也不等。访问对象的时候,我们不会直接是访问对象在内存中的数据,而是通过引用去访问。引用也是一种数据类型,我们可以把它想象为类似 C 语言中指针的东西,它指示了对象在内存中的地址——只不过我们不能够观察到这个地址究竟是什么。
如果我们定义了不止一个引用指向同一个对象,那么这些引用是不相同的,因为引用也是一种数据类型,需要一定的内存空间来保存。但是它们的值是相同的,都指示同一个对象在内存的中位置。比如
String a = "Hello";String b = a;
这里,a 和 b 是不同的两个引用,我们使用了两个定义语句来定义它们。但它们的值是一样的,都指向同一个对象 "Hello"。也许你还觉得不够直观,因为 String 对象的值本身是不可更改的 (像 b = "World"; b = a; 这种情况不是改变了 "World" 这一对象的值,而是改变了它的引用 b 的值使之指向了另一个 String 对象 a)。那么我们用 StringBuffer 来举一个例子:
public class Test {public static void main(String[] args) {StringBuffer a = new StringBuffer("Hello");StringBuffer b = a;b.append(", World");System.out.println("a is " + a);}}运行结果:a is Hello, World
这个例子中 a 和 b 都是引用,当改变了 b 指示的对象的值的时候,从输出结果来看,a 所指示的对象的值也改变了。所以,a 和 b 都指向同一个对象即包含 "Hello" 的一个StringBuffer 对象。
这里我描述了两个要点:
1. 引用是一种数据类型,保存了对象在内存中的地址,这种类型即不是我们平时所说的简单数据类型也不是类实例(对象);
2. 不同的引用可能指向同一个对象,换句话说,一个对象可以有多个引用,即该类类型的变量。
3. 对象是如何传递的呢
关于对象的传递,有两种说法,即“它是按值传递的”和“它是按引用传递的”。这两种说法各有各的道理,但是它们都没有从本质上去分析,即致于产生了争论。既然现在我们已经知道了引用是什么东西,那么现在不妨来分析一下对象作是参数是如何传递的。还是先以一个程序为例:
public class Test {public static void test(StringBuffer str) {str.append(", World!");}public static void main(String[] args) {StringBuffer string = new StringBuffer("Hello");test(string);System.out.println(string);}}运行结果:Hello, World!
test(string) 调用了 test(StringBuffer) 方法,并将 string 作为参数传递了进去。这里 string 是一个引用,这一点是勿庸置疑的。前面提到,引用是一种数据类型,而且不是对象,所以它不可能按引用传递,所以它是按值传递的,它么它的值究竟是什么呢?是对象的地址。
由此可见,对象作为参数的时候是按值传递的,对吗?错!为什么错,让我们看另一个例子:
public class Test {public static void test(String str) {str = "World";}public static void main(String[] args) {String string = "Hello";test(string);System.out.println(string);}}运行结果:Hello
为什么会这样呢?因为参数 str 是一个引用,而且它与 string 是不同的引用,虽然它们都是同一个对象的引用。str = "World" 则改变了 str 的值,使之指向了另一个对象,然而 str指向的对象改变了,但它并没有对 "Hello" 造成任何影响,而且由于 string 和 str 是不同的引用,str 的改变也没有对 string 造成任何影响,结果就如例中所示。
其结果是推翻了参数按值传递的说法。那么,对象作为参数的时候是按引用传递的了?也错!因为上一个例子的确能够说明它是按值传递的。
结果,就像光到底是波还是粒子的问题一样,Java 方法的参数是按什么传递的问题,其答案就只能是:即是按值传递也是按引用传递,只是参照物不同,结果也就不同。
①单纯考虑参数str存的也是一种数据类型,可以看成是值传递。
②考虑参数str它是对象string的一个引用,此时就可看做是引用传递。
4. 正确看待传值还是传引用的问题
要正确的看待这个问题必须要搞清楚为什么会有这样一个问题。
实际上,问题来源于 C,而不是 Java。
C 语言中有一种数据类型叫做指针,于是将一个数据作为参数传递给某个函数的时候,就有两种方式:传值,或是传指针,它们的区别,可以用一个简单的例子说明:
void SwapValue(int a, int b) {int t = a;a = b;b = t;}void SwapPointer(int * a, int * b) {int t = * a;* a = * b;* b = t;}void main() {int a = 0, b = 1;printf("1 : a = %d, b = %d\n", a, b);SwapValue(a, b);printf("2 : a = %d, b = %d\n", a, b);SwapPointer(&a, &b);printf("3 : a = %d, b = %d\n", a, b);}运行结果:1 : a = 0, b = 12 : a = 0, b = 13 : a = 1, b = 0
大家可以明显的看到,按指针传递参数可以方便的修改通过参数传递进来的值,而按值传递就不行。
当 Java 成长起来的时候,许多的 C 程序员开始转向学习 Java,他们发现,使用类似SwapValue 的方法仍然不能改变通过参数传递进来的简单数据类型的值,但是如果是一个对象,则可能将其成员随意更改。于是他们觉得这很像是 C 语言中传值/传指针的问题。但是 Java 中没有指针,那么这个问题就演变成了传值/传引用的问题。可惜将这个问题放在 Java 中进行讨论并不恰当。
讨论这样一个问题的最终目的只是为了搞清楚何种情况才能在方法函数中方便的更改参数的值并使之长期有效。
Java 中,改变参数的值有两种情况,第一种,使用赋值号“=”直接进行赋值使其改变,如例 1 和例 4;第二种,对于某些对象的引用,通过一定途径对其成员数据进行改变,如例 3.对于第一种情况,其改变不会影响到方法该方法以外的数据,或者直接说源数据。而第二种方法,则相反,会影响到源数据——因为引用指示的对象没有变,对其成员数据进行改变则实质上是改变的该对象。
转自考试大 http://www.examda.com/Java/jichu/20090508/092721753.html
发表评论
-
Java Classloader机制解析
2015-07-14 14:14 810做Java开发,对于ClassLoader的机制是必须要熟悉 ... -
JVM Internals
2014-12-05 11:04 750This article explains the ... -
JVM必备指南
2014-11-01 11:20 452本文由 ImportNew - xiafei 翻译自 ant ... -
open jdk源码下载地址
2014-10-13 23:19 1093OpenJDK 和Oracle JDK 共用了大量相同的代码 ... -
Java中System.loadLibrary() 的执行过程
2014-10-10 11:45 6078转自:http://my.oschina.net/wolfc ... -
java 垃圾回收总结
2014-10-03 22:47 691转自:http://www.cnblogs.com/aigo ... -
java中volatile关键字的含义
2014-10-03 22:39 603转自:http://www.cnblogs.com/aigo ... -
java并发编程-Executor框架
2014-10-01 23:40 540Executor框架是指java 5中 ... -
Java中ArrayList和LinkedList区别
2014-09-17 18:48 539转自:http://pengcqu.iteye. ... -
深入理解Java内存模型之系列篇
2014-09-16 11:16 823转自:http://blog.csdn.net/ ... -
Java Thread 总结
2014-09-15 22:39 565转自:http://www.cnblogs.com/Drea ... -
如何停止一个正在运行的java线程
2014-09-15 22:33 1953转自:http://ibruce.info/2013/12 ... -
详解sleep和wait的区别
2014-09-15 22:16 2436转自:http://www.cnblogs.com/Dre ... -
Java多线程总结之由synchronized说开去
2014-09-14 13:11 622转自: http://hellosure.iteye.co ... -
ThreadLocal的正确用法
2014-09-13 23:52 471用法一:在关联数据类中创建private static ... -
Hashtable与ConcurrentHashMap差别
2014-09-06 00:00 879Hashtable与ConcurrentHashMap区别 ... -
JAVA多线程和并发基础面试问答
2014-09-01 22:56 645多线程和并发问题是Jav ... -
java 双重加锁及单例模式
2014-08-25 18:02 1134单例创建模式是一个通用的编程习语。和多线程一起使用时,必需使 ... -
Java内部类的使用小结
2014-08-13 21:45 538内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹 ... -
java sleep和wait的区别和联系
2014-08-10 20:46 627第一种解释: 功 ...
相关推荐
java中传值与传引用,详细讲解java中的传值与传引用
Java是传值还是传址引用
java中传值还是传引用的的认识? 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
Java 是传值还是传引用,问题主要出在对象的传递上,因为 Java 中简单类型没有引用。既然争论中提到了引用这个东西,为了搞清楚这个问题,我们必须要知道引用是什么。 简单的说,引用其实就像是一个对象的名字...
JAVA传值与传引用[整理].pdf
java传值所用的基本方法与java传值时是传引用还是传值
前言在Java中,当对象作为参数传递时,究竟传递的是对象的值,还是对象的引用,这是一个饱受争议的话题。若传的是值,那么函数接收的只是实参本,函数对形参的操作并不
主要介绍了java中的传值与传引用实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Java到底是传引用还是传值Java开发Java经验技巧共3页.pdf.zip
引用类型不像值类型传值那样直接,那么引用类型是怎么样传值的呢?答案就在此文档中。
传值和传引用的问题一直是Java里争论的话题。与C++不同的,Java里面没有指针的概念,Java的设 计者巧妙的对指针的操作进行了管理。事实上,在懂C++的Java程序员眼中,Java到处都是精美绝伦的指 针。
java及C++中传值传递、引用传递和指针方式的理解.docx
很多初学者比较疑惑的地方,看看绝对有帮助的。帮你打好Java的基础知识
主要是对Java方法传值和传引用问题进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助
Java中引用类型传值的代码清单.pdf 学习资料 复习资料 教学资源
传值还是传引用 详细讲解JAVA参数传递机制 一目了然
第一次使用int实验: public class TTEST { private static List<UserEntity> mList = new LinkedList(); public static void main(String[] args) { int a = 0; changeA(a); System.out.println("a = "+a);...
通过对典型程序的研究与分析可以看出JAVA语言的参数传递总是传值调用的,但是对于基本类型的参数和对象类型的参数来说,参数传递的情况不完全相同.Java语言不能直接使用传引用调用,但是可以通过数组的方式模拟传引用...
java 传值还是传引用?代码一目了然,代码中可以测试研究 到底传得什么