【前言】
说明:本文的适用对象为java初学者、如果有读者发现文章中有叙述不妥之处,请指正。
结论:java只有值传递,没有引用传递。
下面我来分析一下。
【一、首先来明确一下"值传递"和"引用传递的"区别】
值传递:是对所传递参数进行一次副本拷贝,对参数的修改只是对副本的修改,函数调用结束,副本丢弃,原来的变量不变(即实参不变)
引用传递:参数被传递到函数时,不复制副本,而是直接将参数自身传入到函数,函数内对参数的任何改变都将反映到原来的变量上。
【二、java中引用的含义】
C++和java中都有引用的概念,但在这两种语言中却有完全不同的含义。C++中我们可以用形如"int &b=a”的形式来定义变量a的一个引用b,b只是a的一个别名,b和a在内存中占同一个存储单元,利用引用机制我们可以在调用函数时实现值的双向传递——即引用传递,看下面代码:
示例一
#include <iostream> using namespace std; int main() { void swap(int &,int &); int i=3,j=5; swap(i,j); cout<<"i="<<i<<"j="<<j<<endl; return 0; } void swap(int &a,int &b) { int temp; temp=a; a=b; b=temp; }
执行上面的程序输出的是i=5 j=3,a和b传递给swap()函数的时候,是传递的他们本身的地址,不是他们的拷贝,所以在函数中对他们的改变可以直接影响到实参a和b,这就是引用传递。
java中的引用更像C++中的指针,当我们定义一个对象时(比如Person p=new Person()),定义的对象实例会放到java堆中,而变量p(即引用)会放到java栈中,p指向堆中的Person对象实例。
【三、对引用传递的认识误区】
为什么有很多人认为java有引用传递呢?一种情况是有人认为调用函数时其参数有可能是引用(如上面的p),所以java有引用传递,这部分人对引用传递根本没有正确的认识;而另一种情况看似有道理,但是仔细分析也是不正确的的,他们往往会用如下的代码来证明他们的观点:
示例二:
class Demo{ int a; public Demo(int a){ this.a=a; } } public class TestQuote{ public static void main(String args[]){ Demo d1=new Demo(1); Demo d2=new Demo(2); System.out.println(d1.a); System.out.println(d2.a); function(d1,d2); System.out.println(d1.a); System.out.println(d2.a); } private static void function(Demo d1,Demo d2){ int a; a=d1.a; d1.a=d2.a; d2.a=a; } }
他们的观点如下:执行上面的代码,调用function()函数以前输出的结果是1、2,调用function()函数之后输出的结果会是2、1,可见在函数内对d1和d2的改变反映到了原来的变量上,要不是不会输出2、1的。
这种解释是很迷惑人的,看上去好像很正确,下面的代码会很好的反驳上面的观点:
示例三:
class Demo{ int a; public Demo(int a){ this.a=a; } } public class TestQuote{ public static void main(String args[]){ Demo d1=new Demo(1); Demo d2=new Demo(2); System.out.println(d1.a); System.out.println(d2.a); function(d1,d2); System.out.println(d1.a); System.out.println(d2.a); } private static void function(Demo d1,Demo d2){ Demo temp; temp=d1; d1=d2; d2=temp; } }
执行上面的代码,调用function()前后程序输出的都是1、2,此程序试图通过调用function()交换d1和d2,但是没有成功,为什么呢?因为d1和d2是值传递,function()中的d1和d2是main()函数中d1和d2的副本,调用完function()不会对main()中的变量产生影响。再看示例二中,function()函数内改变的并不是d1和d2本身的值,而是d1和d2指向的对象的值,调用完function()后d1和d2仍然指向函数调用前的堆地址,即函数参数是栈中的d1和d2,而不是堆中d1和d2指向的对象,即使你在函数中改变了堆中的对象,但没有改变函数参数的值。所以示例二并不是什么引用传递;可见java中只有值传递。
但是网上有很多针对"java值传递和引用传递进行的区别"的文章,如果读者看到的话一定要清楚,其中所说的引用传递是不正确的,他们所说的引用传递就是示例二中的那种情况。不幸的是,网上有很多文章都把示例二中的那样的传递看做引用传递,如果读者看到知道是什么意思就行了。
----------------------华丽的分割线----------------------
本文转自:http://blog.csdn.net/lubiaopan/article/details/4837878
相关推荐
本文将深入探讨Java中的参数传递机制,并通过具体的代码示例和内存分配图解来帮助读者理解按值传递和按引用传递的概念。 #### 二、按值传递的概念与特点 按值传递是指在函数或方法调用过程中,传递给函数或方法的...
在Java编程语言中,了解值传递和引用传递的概念至关重要,因为它们直接影响到函数参数的处理方式。下面将详细探讨这两个概念及其区别。 首先,我们来理解什么是值传递。在Java中,基本数据类型(如int、double、...
标题“Java是值传递,传对象引用也是通过值”揭示了Java中参数传递的核心概念。Java总是以值传递方式进行,这意味着当你将一个变量作为参数传递给方法时,传递的是该变量所存储值的一个副本。然而,对于对象类型的...
Java参数传递的规则是:**Java只使用值传递,但这种值传递对于对象参数表现为类似引用传递的行为。** 在值传递中,函数或方法接收的是原始数据类型(如int、double、boolean)参数的副本。例如,如果有一个方法...
### Java引用变量传递诡异之处详解 #### 背景与问题描述 在Java编程语言中,对于引用类型变量的理解及其实现方式一直是开发者们容易混淆的地方。尤其是当涉及到方法调用过程中引用变量的传递时,更是如此。本文将...
在本教程中,我们将探讨如何在Java和HTML的结合中实现值传递,以便在网页上绘制圆圈,这对于初学者来说是一个很好的实践项目。 首先,我们要理解Java和HTML之间的交互。通常,这种交互是通过Servlet或JSP(Java...
我们将详细探讨Java中的值传递和引用传递的概念,以及它们之间的区别。 首先,值传递是Java中最基本的参数传递方式。当一个变量作为参数传递给方法时,实际上是传递了该变量存储值的一个副本。这意味着在方法内部对...
本文将深入探讨Java中的方法调用、值传递与引用传递,并通过字节码分析来进一步理解这些概念。 首先,我们来看方法调用。在Java中,方法是一组完成特定任务的代码块,可以通过方法名来调用执行。方法调用的基本语法...
在编程语言中,值传递和引用传递是函数参数传递的两种基本方式,它们涉及到内存管理、数据安全以及程序效率等多个重要方面。这篇文章将深入探讨这两种传递方式,并通过内存解析来帮助理解它们的工作原理。 首先,...
Java 参数传递机制是编程中的重要概念,尤其是在Java中,它涉及到“值传递”和“引用传递”的理解。这里我们将深入探讨这两个概念,并结合给定的示例代码进行解析。 首先,我们看“值传递”。在Java中,基本类型...
### 浅析Java引用类型和方法参数传递 #### 一、引言 在Java编程语言中,理解数据类型的处理方式对于编写高效、可维护的代码至关重要。本文将深入探讨Java中的引用类型及其如何影响方法参数的传递机制。通过具体实例...
本文将深入探讨Java与C++这两种广泛使用的编程语言中参数传递的方式,包括值传递、引用传递以及C++中的指针传递,并通过具体的代码示例来帮助理解这些概念。 #### 值传递 值传递是最简单的参数传递方式之一,它指...
- **传值**:基本数据类型(如int、char等)的参数传递是值传递,也就是说,方法内部对参数的修改不会影响到方法外部的变量。 - **传引用**:对于对象,Java总是采用引用传递。这意味着,即使在方法中改变对象的...
在本例中,我们探讨的是如何将前台Flex中输入的用户名和密码封装成一个值对象(Value Object, VO),并将其传递给后端Java服务进行处理。这种模式可以有效地提高代码的复用性和维护性,并简化前后端之间的通信过程。...
"java客户端服务器传递对象"这个主题涉及到的核心知识点主要包括Java RMI(Remote Method Invocation,远程方法调用)、对象序列化以及网络通信的基本原理。下面我们将深入探讨这些概念。 1. **Java RMI**: RMI是...
本章节主要探讨的是在面向对象编程中一个重要的概念:值传递与引用传递。理解这两个概念对于编写高效、安全的Java程序至关重要。 值传递是指当函数或方法调用时,参数的副本被传入到函数内部。这意味着在函数内部对...
根据标题和描述,本文将深入探讨Java中函数参数传递的机制,究竟是值传递还是引用传递。实际上,Java只支持值传递,但这种值传递对于引用类型(对象)的数据有着特殊含义。 首先,值传递是指当函数调用时,实际参数...
Java中的参数传递方式有两种,即值传递和引用传递,但需要注意的是,Java只支持值传递。下面我们将详细探讨这两种传递方式及其在实际编程中的表现。 1. 值传递(Value Passing) 值传递指的是在调用方法时,将变量...
本文将深入探讨如何通过JNI在Java中传递对象到C代码。 首先,我们需要理解Java对象在JNI中的表示方式。Java对象在本地代码中通常被表示为`jobject`指针,这是一个通用类型,可以指向任何Java对象,包括类实例、数组...
对于引用类型,Java看似采用“按引用传递”(Pass by Reference),但实际是“按值传递对象的引用”。这意味着当一个对象引用作为参数传递时,方法得到的是该对象引用的一个副本。因此,尽管不能改变引用本身,但...