`
h416756139
  • 浏览: 367410 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java传值or传引用 一

    博客分类:
  • java
阅读更多

第一种说法

1. 简单类型是按值传递的

  Java 方法的参数是简单类型的时候,是按值传递的 (pass by value)。这一点我们可以通过一个简单的例子来说明:

/*  1 */

/**

@(#) Test.java *

 @author fancy */

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 = true
In test(boolean) : test = false
After test(boolean) : test = true

   不难看出,虽然在 test(boolean) 方法中改变了传进来的参数的值,但对这个参数源变量本身并没有影响,即对 main(String[]) 方法里的 test 变量没有影响。那说明,参数类型是简单类型的时候,是按值传递的。以参数形式传递简单类型的变量时,实际上是将参数的值作了一个拷贝传进方法函数的,那么 在方法函数里再怎么改变其值,其结果都是只改变了拷贝的值,而不是源值。

2. 什么是引用

  Java 是传值还是传引用,问题主要出在对象的传递上,因为 Java 中简单类型没有引用。既然争论中提到了引用这个东西,为了搞清楚这个问题,我们必须要知道引用是什么。

   简单的说,引用其实就像是一个对象的名字或者别名 (alias),一个对象在内存中会请求一块空间来保存数据,根据对象的大小,它可能需要占用的空间大小也不等。访问对象的时候,我们不会直接是访问对象 在内存中的数据,而是通过引用去访问。引用也是一种数据类型,我们可以把它想象为类似 C 语言中指针的东西,它指示了对象在内存中的地址——只不过我们不能够观察到这个地址究竟是什么。

  如果我们定义了不止一个引用指向同一个对象,那么这些引用是不相同的,因为引用也是一种数据类型,需要一定的内存空间来保存。但是它们的值是相同的,都指示同一个对象在内存的中位置。比如

String a = "Hello";
String b = a;

   这里, b 是不同的两个引用,我们使用了两个定义语句来定义它们。但它们的值是一样的,都指向同一个对象 "Hello"。也许你还觉得不够直观,因为 String 对象的值本身是不可更改的 ( b = "World"; b = a; 这种情况不是改变了 "World" 这一对象的值,而是改变了它的引用 b 的值使之指向了另一个 String 对象 a)。那么我们用 StringBuffer 来举一个例子:

/*  2 */

/**

@(#) Test.java *

@author fancy */

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 指示的对象的值的时候,从输出结果来看,所指示的对象的值也改变了。所以, b 都指向同一个对象即包含 "Hello" 的一个 StringBuffer 对象。

  这里我描述了两个要点:

  1. 引用是一种数据类型,保存了对象在内存中的地址,这种类型即不是我们平时所说的简单数据类型也不是类实例(对象)
  2. 不同的引用可能指向同一个对象,换句话说,一个对象可以有多个引用,即该类类型的变量。

3. 对象是如何传递的呢

  关于对象的传递,有两种说法,即它是按值传递的它是按引用传递的。这两种说法各有各的道理,但是它们都没有从本质上去分析,即致于产生了争论。

  既然现在我们已经知道了引用是什么东西,那么现在不妨来分析一下对象作是参数是如何传递的。还是先以一个程序为例:

/*  3 */

/**

@(#) Test.java *

@author fancy */

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 是一个引用,这一点是勿庸置疑的。前面提到,引用是一种数据类型,而且不是对象,所以它不可能按引用传递,所以它是按值传递的,它么它的值究竟是什么呢? 是对象的地址。

  由此可见,对象作为参数的时候是按值传递的,对吗?错!为什么错,让我们看另一个例子:

/*  4 */

/** *

@(#) Test.java *

 @author fancy */

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 方法的参数是按什么传递的问题,其答案就只能是:即是按值传递也是按引用传递,只是参照物不同,结果也就不同。

4. 正确看待传值还是传引用的问题

  要正确的看待这个问题必须要搞清楚为什么会有这样一个问题。

  实际上,问题来源于 C,而不是 Java

  语言中有一种数据类型叫做指针,于是将一个数据作为参数传递给某个函数的时候,就有两种方式:传值,或是传指针,它们的区别,可以用一个简单的例子说明:

/*  5 */

/** *

@(#) test.c *

 @author fancy */

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 = 1
2 : a = 0, b = 1
3 : a = 1, b = 0

  大家可以明显的看到,按指针传递参数可以方便的修改通过参数传递进来的值,而按值传递就不行。

   当 Java 成长起来的时候,许多的 C 程序员开始转向学习 Java,他们发现,使用类似 SwapValue 的方法仍然不能改变通过参数传递进来的简单数据类型的值,但是如果是一个对象,则可能将其成员随意更改。于是他们觉得这很像是 C 语言中传值/传指针的问题。但是 Java 中没有指针,那么这个问题就演变成了传值/传引用的问题。可惜将这个问题放在 Java 中进行讨论并不恰当。

  讨论这样一个问题的最终目的只是为了搞清楚何种情况才能在方法函数中方便的更改参数的值并使之长期有效。

   Java 中,改变参数的值有两种情况,第一种,使用赋值号“=”直接进行赋值使其改变,如例 1 和例 4;第二种,对于某些对象的引用,通过一定途径对其成员数据进行改变,如例 3。对于第一种情况,其改变不会影响到方法该方法以外的数据,或者直接说源数据。而第二种方法,则相反,会影响到源数据——因为引用指示的对象没有变,对 其成员数据进行改变则实质上是改变的该对象。

转自:http://blog.csdn.net/baobeiSimple/archive/2007/08/05/1727053.aspx

 

 

分享到:
评论

相关推荐

    JAVA传值与传引用[整理].pdf

    JAVA传值与传引用[整理].pdf

    java中传值与传引用

    在Java编程语言中,函数调用时的参数传递方式有两种:传值(Passing by Value)和传引用(Passing by Reference)。虽然Java官方文档中并未明确指出有传引用这一概念,但在实际操作中,Java的行为类似于传引用,尤其...

    引用类型传值方法

    因此,当我们将一个引用类型变量赋值给另一个变量时,实际上是复制了这个引用,而不是复制整个对象。 引用类型的传值行为体现在函数调用和方法参数传递上。当我们把一个引用类型变量作为参数传递给函数时,并不会...

    Java中的传值与传引用实现过程解析

    Java中的传值与传引用是Java编程语言中的一种基础概念,它们是Java函数中参数传递的两种方式。 Java中的传值是指函数参数的值被复制到函数内部,在函数内部对参数的修改不会影响原来的参数值。 Java中的传引用是指...

    java及C++中传值传递、引用传递和指针方式的理解.docx

    ### Java及C++中传值传递、引用传递和指针方式的理解 在程序设计语言中,函数调用时参数的传递方式对理解程序的行为至关重要。本文将深入探讨Java与C++这两种广泛使用的编程语言中参数传递的方式,包括值传递、引用...

    lotus domnio java代理传值

    "lotus domnio java代理传值"这个主题主要涉及如何在Java代码中创建和使用代理,并在代理之间传递参数。 首先,让我们了解一下Lotus Domino Java代理的基本概念。在Lotus Domino Designer中,Java代理是用Java语言...

    Java SE程序 界面传值问题

    Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE程序 界面传值问题Java SE...

    JSP中java代码与js之间的传值

    1. **Java到JavaScript的传值**: - **通过HTML标签属性**:Java代码可以通过设置HTML元素的属性来传递值。例如,`<input type="hidden" id="myValue" value="<%= javaVariable %>">`,这里的`javaVariable`是Java...

    传值传名传地址.zip

    传名在Python中可以被视为一种特殊形式的传引用,因为Python中的所有对象都是引用类型,函数调用时传递的是对象的引用。这意味着,即使在函数内部修改形参,也会直接影响到实参。 最后,我们来探讨**传地址**。传...

    42.传值和传引用.doc-综合文档

    在编程领域,传值和传引用是两种不同的参数传递机制,它们主要应用于函数调用时对参数的处理。本文将详细探讨这两种机制及其在不同编程环境中的应用,以C++、Java、C#等文本编程语言和LabVIEW可视化编程语言为例。 ...

    Java中引用类型传值的代码清单.pdf

    当我们讨论“引用类型传值”时,意味着在方法调用时,传递的是对象引用的一个副本,而不是对象本身。以下是对给定代码清单的详细解释: 1. `Circle.java` 文件定义了一个名为 `Circle` 的类,它包含一个 `double` ...

    android activityIntent 传值 传对象

    1. **基本数据类型的传值** Intent提供了putExtra()方法来传递基本数据类型,如字符串、整型、浮点型等。例如,要在Intent中传递一个字符串,可以这样操作: ```java Intent intent = new Intent(this, ...

    Java中对象与引用

    1. **一个引用可以指向多个对象**: 当我们声明一个引用变量并将其指向某个对象时,可以通过这个引用变量来访问该对象的属性和方法。如果改变引用变量的指向,则原对象仍然存在,但不再被当前引用变量所访问。 ```...

    jsp网页产生json传值到java的servlet,再回传到jsp页面

    在Web开发中,JavaServer Pages (JSP) 和 Java Servlets 是常见的技术组合,用于构建动态、交互式的网页。在本场景中,我们探讨的是如何使用JSP通过Ajax(Asynchronous JavaScript and XML)发送JSON(JavaScript ...

    Java-Java面向对象中引用传递教程

    1. **传值与传引用的区别** - **传值**:基本数据类型(如int、char等)的参数传递是值传递,也就是说,方法内部对参数的修改不会影响到方法外部的变量。 - **传引用**:对于对象,Java总是采用引用传递。这意味着...

    Java仙剑奇侠传源代码

    《Java仙剑奇侠传源代码》是一款基于Java J2ME平台开发的手机游戏,它再现了经典单机游戏《仙剑奇侠传》的世界观和游戏机制。J2ME,全称为Java Micro Edition,是Java平台的一个子集,主要用于嵌入式设备和移动设备...

    简单的网页传值

    网页传值是Web开发中的基本操作,用于在不同的页面间传递数据,使用户的状态得以保持。本主题将深入探讨两种常见的方法:Cookie和Session。理解并掌握这两种技术对于构建动态和交互性强的网站至关重要。 首先,我们...

    浅谈Java中方法的参数传值.pdf

    虽然Java实际上不支持纯粹的按引用传递,而是采用了一种特殊的方式——“按值传递引用”的机制。这种机制意味着传递的是对象引用的副本,即实际上传递的是对象内存地址的副本。因此,虽然在方法内不能直接更改引用...

Global site tag (gtag.js) - Google Analytics