这个很基础很基础的问题今天才搞明白。
今天和同学讨论C++的一个函数的参数是指针的时候我无意说了一句,要是java的话就不用这么复杂了,一律传引用,于是就引起了java到底是传值还是传引用的讨论。
我之前的认识是这样的:在处理简单数据类型的时候毫无疑问是传值的,而当对象作为函数的参数的时候则是传的是引用。
但是事实证明我的认识还是错的,现在我当然明白了java的传参究竟是传什么,下面简单说一下:
可以说java不存在传递引用的情况,java只有一种传递方法就是传值,但是这个传值还是有一点小小的不同,例如在函数
java 代码
- public void testRef(SomeClass sc) {
-
- sc.someMethod();
-
-
- }
中,其中当调用此函数时
java 代码
- SomeClass someClass = new SomeClass();
- testRef(someClass);
作为形参的sc会生成实参someClass的一个拷贝,但是这个拷贝是someClass在栈空间指向堆空间的地址的拷贝,我们知道,当使用诸如A a = new A();的时候,实际上A a是在栈空间中获得了一个A对象的“引用”,当使用new A();初始化这个对象是,则是在堆空间中申请了空间同时将a指向堆空间中的地址。有了这些知识就不难理解,在方法testRef中通过
.的
操作其实就是对传进来的实参someClass进行操作,因为此时sc是someClass地址,而若执行了sc = new SomeClass();sc的
.的
操作变不会再对someClass产生影响,究其原因,是因为此时sc已经指向了堆空间中另一块SomeClass类大小的地址。
简单一点就是说,java在传递参数过程中若参数是对象传递的是对象地址的拷贝,也就是说传递的是地址的值。
这个故事告诉我:凡事不可想当然
补充,今天看sun出的SCJP指南,上面的解释比较科学
可能会问你是否理解传递值到方法中时会发生什么结果。如果方法中的代码改变了变量,对外部的方法是否可见?直接引用 Peter van der Lindens 的 Java 程序员解答的一段话(在 http://www.afu.com)
//引用
所有的变量(基本类型值和对象的引用值)都是值传递。但是这不是全部情况,对象是经常通过 Java 的引用变量来操作的。所以也可以说对象是通过引用传递的(
引用变量通过值传递) 。这是变量不使用对象的值而是像前一个问题那样描述的使用对象引用的值的结果。最后一行:调用者对基本类型参数(int,char 等)的拷贝在相应参数变化时不会改变。但是,在被调用方法改变相应作为参数传递的对象(引用)字段时,调用者的对象也改变其字段。
//引用结束
如果你来自 C++背景,你可能对值传递参数和用&符号传递引用参数熟悉。在 Java 中没有这样的选择,所有的都是值传递。但是看起来并不总是这样。如果你传递的对象是对象的引用,你不能直接对对象的引用进行操作。 所以如果你操作一个传递到方法的对象的字段, 结果就好像你按引用传递(任何改变结果都会返回到调用函数) 将对象引用作为方法变量
请看下面的例子
java 代码
- class ValHold{
- public int i = 10;
- }
- public class ObParm{
- public static void main(String argv[]){
- ObParm o = new ObParm();
- o.amethod();
- }
- public void amethod(){
- ValHold v = new ValHold();
- v.i=10;
- System.out.println("Before another = "+ v.i);
- another(v);
- System.out.println("After another = "+ v.i);
- }
- public void another(ValHold v){
- v.i = 20;
- System.out.println("In another = "+ v.i);
- }
- }
程序的输出结果是
Before another = 10
In another = 20
After another = 20
看变量 i 是怎么被修改的。如果 Java 总是值传递(也就是对变量的拷贝) ,它是怎么被修改的呢?过程是这样的方法收到了句柄的拷贝或者对象的引用, 但是这个引用的作用类似于指向真实的指针。对这个字段的改变会反映到它所指的值。这有些像是在 C/C++中指针的自动间接应用的的作用。
分享到:
相关推荐
"java中传值还是传引用的认识" Java 中的参数传递是值传递还是引用传递?这是一个经常引发讨论的问题。在 Java 中,参数传递是按值传递的,也就是说,传递给方法的参数是一个副本,而不是原始值本身。 当一个对象...
### Java是传值还是传址引用 #### 一、简单类型是按值传递的 Java在处理简单数据类型(如int、boolean等)时采用的是按值传递的方式。这意味着当你将一个简单类型的值作为参数传递给一个方法时,实际上传递的是这...
在Java编程语言中,函数调用时的参数传递方式有两种:传值(Passing by Value)和传引用(Passing by Reference)。虽然Java官方文档中并未明确指出有传引用这一概念,但在实际操作中,Java的行为类似于传引用,尤其...
"Java中的传值与传引用实现过程解析" Java中的传值与传引用是Java编程语言中的一种基础概念,它们是Java函数中参数传递的两种方式。 Java中的传值是指函数参数的值被复制到函数内部,在函数内部对参数的修改不会...
JAVA传值与传引用[整理].pdf
许多人认为对象是按引用传递,而实际上,Java总是按值传递,包括对象。这里的“值”指的是对象的引用,而不是对象本身。这与C++或C#等其他语言中对象的传递方式有所不同。 首先,我们需要理解Java中的引用概念。当...
理解Java中的传值与传引用对于编写正确且预期的行为代码至关重要。在编写函数时,应清楚地知道参数如何被传递,以及这将如何影响函数的可读性和行为。在实际编程中,合理运用这些知识能帮助避免许多常见的错误和困惑...
在计算机编程领域,特别是对于面向对象语言如Java而言,“传值”与“传引用”的概念是理解数据传递机制的关键所在。Java作为一种广泛使用的高级编程语言,在设计之初就考虑到了如何避免C/C++等语言中的复杂性,特别...
Java编程语言在处理参数传递时遵循一种特殊的方式,它既不是纯粹的按值传递,也不是纯粹的按引用传递。理解这一点对于深入学习Java至关重要。在Java中,基本数据类型(如int、float、char等)是按值传递的,而对象则...
本篇文章将详细探讨引用类型的传值方式。 首先,理解引用类型的概念至关重要。引用类型包括类(classes)、接口(interfaces)、数组以及委托(delegates),它们在内存中的存储方式与值类型截然不同。对于引用类型...
根据标题和描述,我们将深入探讨Java中传值与引用的区别,以及它们在实际编程中的应用。 首先,Java是一种“总是按值传递”的语言。这意味着无论是基本类型还是引用类型,当作为参数传递时,都会有一个副本被创建并...
### Java及C++中传值传递、引用传递和指针方式的理解 在程序设计语言中,函数调用时参数的传递方式对理解程序的行为至关重要。本文将深入探讨Java与C++这两种广泛使用的编程语言中参数传递的方式,包括值传递、引用...
在Java编程语言中,方法参数传递机制涉及到两个主要概念:传值和传引用。了解这两个概念对于编写高效、可靠的代码至关重要。本篇文章将深入探讨Java中的方法传值和传引用问题。 首先,让我们理解什么是传值。在Java...
- **通过JSP表达式语言(EL)**:使用EL表达式,如 `${javaVariable}`,可以直接在JavaScript代码中引用JavaBean或作用域内的变量。 2. **JavaScript到Java的传值**: - **表单提交**:通过JavaScript修改表单字段的...
Java只支持两种类型的参数传递:基本数据类型(如int、double等)的传值和引用类型(如类对象)的传值。以下是对给定代码清单的详细解释: 1. **基本数据类型传值**: 在Java中,基本数据类型的参数传递是按值传递...
使用`NewGlobalRef`和`DeleteGlobalRef`管理Java对象的引用,避免Java对象被过早回收。 7. **回调机制** Java可以调用C++,反之亦然。在C++中调用Java方法称为回调,这需要定义一个Java方法并传递其地址给C++,C++...
当我们讨论“引用类型传值”时,意味着在方法调用时,传递的是对象引用的一个副本,而不是对象本身。以下是对给定代码清单的详细解释: 1. `Circle.java` 文件定义了一个名为 `Circle` 的类,它包含一个 `double` ...
总结起来,理解传值、传名(或传引用)和传地址的异同是编程基础的重要组成部分。它们影响着函数的可读性、效率以及程序的行为。在编写代码时,根据具体需求选择合适的参数传递方式,是提升代码质量的关键。