`
h416756139
  • 浏览: 365679 次
  • 性别: 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中传值与传引用

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

    java中传值还是传引用的的认识

    "java中传值还是传引用的认识" Java 中的参数传递是值传递还是引用传递?这是一个经常引发讨论的问题。在 Java 中,参数传递是按值传递的,也就是说,传递给方法的参数是一个副本,而不是原始值本身。 当一个对象...

    Java是传值还是传址引用

    ### Java是传值还是传址引用 #### 一、简单类型是按值传递的 Java在处理简单数据类型(如int、boolean等)时采用的是按值传递的方式。这意味着当你将一个简单类型的值作为参数传递给一个方法时,实际上传递的是这...

    Java传值还是引用

    根据标题和描述,我们将深入探讨Java中传值与引用的区别,以及它们在实际编程中的应用。 首先,Java是一种“总是按值传递”的语言。这意味着无论是基本类型还是引用类型,当作为参数传递时,都会有一个副本被创建并...

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

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

    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...

    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); ...

    传值传名传地址.zip

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

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

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

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

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

    Java中对象与引用

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

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

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

    Java仙剑奇侠传源代码

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

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

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

    基于or-tools的人员排班问题建模求解(JavaAPI)

    `OR-Tools`是谷歌推出的一个开源的、强大的优化工具箱,它支持多种编程语言,包括Java。本篇文章将深入探讨如何利用OR-Tools的Java API解决一个具体的实例——“人员排班问题”。 人员排班问题是一个典型的线性规划...

    页面传值与后台传值

    在IT行业中,页面传值与后台传值是Web开发中的基础技能,特别是在使用Java进行后端处理时。这里我们将深入探讨这两个概念,并结合标签“jsp”和“json”,阐述它们在实际开发中的应用。 首先,页面传值指的是前端...

    java 常见的四种引用

    ### Java 常见的四种引用详解 #### 引言 在Java中,为了更好地管理对象的生命周期,从JDK 1.2开始引入了四种不同级别的引用类型:强引用、软引用、弱引用和虚引用。每种引用类型都有其特定的应用场景,通过灵活运用...

Global site tag (gtag.js) - Google Analytics