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

JAVA基础(Java参数传值还是传引用)

阅读更多
参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递。写它是为了揭穿普遍存在的一种神话,即认为 Java 应用程序按引用传递参数,以避免因依赖“按引用传递”这一行为而导致的常见编程错误。
  对此节选的某些反馈意见认为,我把这一问题搞糊涂了,或者将它完全搞错了。许多不同意我的读者用 C++ 语言作为例子。因此,在此栏目中我将使用 C++ 和 Java 应用程序进一步阐明一些事实。
  要点
  读完所有的评论以后,问题终于明白了,考试大提示: 至少在一个主要问题上产生了混淆。因为对象是按引用传递的。对象确实是按引用传递的;节选与这没有冲突。节选中说所有参数都是按值 -- 另一个参数 -- 传递的。下面的说法是正确的:在 Java 应用程序中永远不会传递对象,而只传递对象引用。因此是按引用传递对象。但重要的是要区分参数是如何传递的,这才是该节选的意图。Java 应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数。参数可以是对象引用,而 Java 应用程序是按值传递对象引用的。
  C++ 和 Java 应用程序中的参数传递
  Java 应用程序中的变量可以为以下两种类型之一:引用类型或基本类型。当作为参数传递给一个方法时,处理这两种类型的方式是相同的。两种类型都是按值传递的;没有一种按引用传递。这是一个重要特性,正如随后的代码示例所示的那样。
  在继续讨论之前,定义按值传递和按引用传递这两个术语是重要的。按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。
  上面的这些是很重要的,请大家注意以下几点结论,这些都是我认为的上面的文章中的精华和最终的结论:
  1、对象是按引用传递的
  2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
  3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
  4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
  首先考试大来看看第一点:对象是按引用传递的
  确实,这一点我想大家没有任何疑问,例如:
  class Test01
  {
  public static void main(String[] args)
  {
  StringBuffer s= new StringBuffer("good");
  StringBuffer s2=s;
  s2.append(" afternoon.");
  System.out.println(s);
  }
  }
  对象s和s2指向的是内存中的同一个地址因此指向的也是同一个对象。
  如何解释“对象是按引用传递的”的呢?
  这里的意思是进行对象赋值操作是传递的是对象的引用,因此对象是按引用传递的,有问题吗?
  程序运行的输出是:
  good afternoon.
  这说明s2和s是同一个对象。
  这里有一点要澄清的是,这里的传对象其实也是传值,因为对象就是一个指针,这个赋值是指针之间的赋值,因此在java中就将它说成了传引用。(引用是什么?不就是地址吗?地址是什么,不过就是一个整数值)
  再看看下面的例子:
  class Test02
  {
  public static void main(String[] args)
  {
  int i=5;
  int i2=i;
  i2=6;
  System.out.println(i);
  }
  }
  程序的结果是什么?5!!!
  这说明什么,原始数据类型是按值传递的,这个按值传递也是指的是进行赋值时的行为下一个问题:Java 应用程序有且仅有的一种参数传递机制,即按值传递
  class Test03
  {
  public static void main(String[] args)
  {
  StringBuffer s= new StringBuffer("good");
  StringBuffer s2=new StringBuffer("bad");
  test(s,s2);
  System.out.println(s);//9
  System.out.println(s2);//10
  }
  static void test(StringBuffer s,StringBuffer s2) {
  System.out.println(s);//1
  System.out.println(s2);//2
  s2=s;//3
  s=new StringBuffer("new");//4
  System.out.println(s);//5
  System.out.println(s2);//6
  s.append("hah");//7
  s2.append("hah");//8
  }
  }
  程序的输出是:
  good
  bad
  new
  good
  goodhah
  bad
  考试大提示: 为什么输出是这样的?
  这里需要强调的是“参数传递机制”,它是与赋值语句时的传递机制的不同。
  我们看到1,2处的输出与我们的预计是完全匹配的
  3将s2指向s,4将s指向一个新的对象
  因此5的输出打印的是新创建的对象的内容,而6打印的原来的s的内容
  7和8两个地方修改对象内容,但是9和10的输出为什么是那样的呢?
  Java 应用程序有且仅有的一种参数传递机制,即按值传递。
  至此,我想总结一下我对这个问题的最后的看法和我认为可以帮助大家理解的一种方法:
  我们可以将java中的对象理解为c/c++中的指针
  例如在c/c++中:
  int *p;
  print(p);//1
  *p=5;
  print(*p);//2
  1打印的结果是什么,一个16进制的地址,2打印的结果是什么?5,也就是指针指向的内容。
  即使在c/c++中,这个指针其实也是一个32位的整数,我们可以理解我一个long型的值。
  而在java中一个对象s是什么,同样也是一个指针,也是一个int型的整数(对于JVM而言),我们在直接使用(即s2=s这样的情况,但是对于System.out.print(s)这种情况例外,因为它实际上被晃猄ystem.out.print(s.toString()))对象时它是一个int的整数,这个可以同时解释赋值的传引用和传参数时的传值(在这两种情况下都是直接使用),而我们在s.XXX这样的情况下时s其实就是c/c++中的*s这样的使用了。这种在不同的使用情况下出现不同的结果是java为我们做的一种简化,但是对于c/c++程序员可能是一种误导。java中有很多中这种根据上下文进行自动识别和处理的情况,下面是一个有点极端的情况:
  class t
  {
  public static String t="t";
  public static void main(String[] args)
  {
  t t =new t();
  t.t();
  }
  static void t() {
  System.out.println(t);
  }
  }
  (关于根据上下文自动识别的内容,有兴趣的人以后可以看看我们翻译的《java规则》)
  1、对象是按引用传递的
  2、Java 应用程序有且仅有的一种参数传递机制,即按值传递
  3、按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
  4、按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本
  三句话总结一下:
  1.对象就是传引用
  2.原始类型就是传值
  3.String类型因为没有提供自身修改的函数,每次操作都是新生成一个String对象,所以要特殊对待。可以认为是传值。
分享到:
评论

相关推荐

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

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

    java的传值与传值后的改变

    理解Java中的传值与传引用对于编写正确且预期的行为代码至关重要。在编写函数时,应清楚地知道参数如何被传递,以及这将如何影响函数的可读性和行为。在实际编程中,合理运用这些知识能帮助避免许多常见的错误和困惑...

    Java是传值还是传址引用

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

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

    Java方法参数传值是Java编程中的基础知识点,涉及变量、数据类型和方法调用的机制。在Java中,数据类型分为基本数据类型和引用数据类型。基本数据类型包括布尔型(boolean)、字节型(byte)、短整型(short)、整型...

    java中传值与传引用

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

    23.Java对象作为参数传递是传值还是传引用1

    总结起来,Java中对象作为参数传递时,传递的是对象引用的副本,而不是对象本身。这意味着函数可以修改对象的状态,因为它持有相同的引用,但不能改变对象引用指向另一个不同的对象。这种行为与基本数据类型不同,...

    java的传值与传引用详解

    ### Java的传值与传引用详解 ...综上所述,理解Java中的传值与传引用的概念,需要区分简单类型和对象类型的不同处理方式,并且明确传递的是值的副本还是引用的副本。这对于编写高效、正确的Java程序非常重要。

    Java传值还是引用

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

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

    Java中,方法参数的传递主要有两种方式:值传递(Pass by Value)和引用传递(Pass by Reference)。不过,Java并没有真正的引用传递,而是通过对象引用来模拟引用传递的效果。下面我们详细讨论这两种方式。 2. 值...

    引用类型传值方法

    引用类型的传值行为体现在函数调用和方法参数传递上。当我们把一个引用类型变量作为参数传递给函数时,并不会创建该对象的新副本,而是复制了这个引用。这意味着函数内部对对象的任何修改都会影响到原始对象,因为...

    Java到底是传引用还是传值Java开发Java经验技巧共

    Java编程语言在处理参数传递时遵循一种特殊的方式,它既不是纯粹的按值传递,也不是纯粹的按引用传递。理解这一点对于深入学习Java至关重要。在Java中,基本数据类型(如int、float、char等)是按值传递的,而对象则...

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

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

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

    - **通过JSP表达式语言(EL)**:使用EL表达式,如 `${javaVariable}`,可以直接在JavaScript代码中引用JavaBean或作用域内的变量。 2. **JavaScript到Java的传值**: - **表单提交**:通过JavaScript修改表单字段的...

    Java中参数传值的代码清单.pdf

    Java只支持两种类型的参数传递:基本数据类型(如int、double等)的传值和引用类型(如类对象)的传值。以下是对给定代码清单的详细解释: 1. **基本数据类型传值**: 在Java中,基本数据类型的参数传递是按值传递...

    Java参数传递PPT

    Java参数传递的规则是:**Java只使用值传递,但这种值传递对于对象参数表现为类似引用传递的行为。** 在值传递中,函数或方法接收的是原始数据类型(如int、double、boolean)参数的副本。例如,如果有一个方法...

    Java语言的方法参数浅析

    通过对典型程序的研究与分析可以看出JAVA语言的参数传递总是传值调用的,但是对于基本类型的参数和对象类型的参数来说,参数传递的情况不完全相同.Java语言不能直接使用传引用调用,但是可以通过数组的方式模拟传引用...

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

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

    Java的引用和函数参数传递

    #### 一、Java中的引用基础 在Java中,对象的引用扮演着类似于其他编程语言(如C/C++)中指针的角色,但是Java的引用比传统的指针更加安全且易于管理。这是因为Java的设计者们刻意避免了一些容易引发错误的操作,...

    浅析Java方法传值和传引用问题

    在Java编程语言中,方法参数传递机制涉及到两个主要概念:传值和传引用。了解这两个概念对于编写高效、可靠的代码至关重要。本篇文章将深入探讨Java中的方法传值和传引用问题。 首先,让我们理解什么是传值。在Java...

Global site tag (gtag.js) - Google Analytics