【Stackoverflow好问题】Java的参数,是按值传递还是按引用传递

明确地说,java是按值传递的!java的世界里,都是按值传递。其实按值、按引用都只是个概念,关键是我们如何去理解java传参的本质。下面就结合一个例子来说

有些情况下,传递的值,其内容是个引用,这一点容易让人产生困惑。

请看下面的例子

首先有如下代码

Dog myDog = new Dog("Rover");
foo(myDog);

这时,你传给了foo函数一个值,这个值的内容,就是Rover这只dog的内存地址(这只是粗略的说明,因为在java中,这个地址并非是真正的地址)

假设这时候Rover这只狗的地址是42,那么我们就是传了42这个地址给foo方法

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC}

在foo方法中,是这样一个过程

1、参数 someDog的值是一个地址(42)

2、在AAA这一行:

因为someDog代表了42那只狗,42这只狗的名字,从Rover被改成了Max

3、在BBB这一行:

这就是关键的地方了,又new了一只dog,new 意味着又在新的地址空间放上了一只Dog,我们假设其地址是74。这时,someDog的值,会从42变成了74

4、在CCC这一行:

这时候的修改,是对74那只狗的修改,而非42

因此,对于foo的参数someDog来说,它是一个值,而非引用。它是一个值,因此他的值任意改变,例如从例子中的地址42改成74。它不是一个引用。如果它是引用,那么在foo方法内部的修改(包括BBB、CCC这两行),都应该会对42地址空间的dog产生影响

不细究概念了,再总结下Java初学者容易犯错的地方:

假如你想像例子一样

Object a = new Object();

foo(a);//在方法内部修改a的属性值

return a;//希望此时的a已经是修改后的值

要切记,这个Objct一定要在调用方法前,就初始化好(new一个),然后再作为参数传进去,之后在方法中再修改bean的某些属性,才会影响到之前初始化的这个Object;如果在方法内再执行new操作,实际已经指向了其他的地址空间

知识补充:

1、什么是值传递?

指的是在方法调用时,传递的参数是按值的拷贝传递。按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了,每个值都对应到一个地址空间

2、什么是引用传递

指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

stackoverflow链接

http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value

专栏介绍:

非常喜欢stackoverflow,总能在上面找到疑难杂症的解决办法。偶然发现该网站有一个热度榜单。于是精选了热度较高的一些问题,阅读每个问题的答案,然后按照自己的理解梳理出来。因此,这些文章不是真正的翻译,而是按照自己的理解做了一些增删、润色,希望能把上面的讨论,更精简有效地分享给大家。

如需转载,请注明原文地址

http://blog.csdn.net/lizeyang

时间: 2024-08-29 14:15:31

【Stackoverflow好问题】Java的参数,是按值传递还是按引用传递的相关文章

JavaScript中函数参数的按值传递与按引用传递(即按地址传递)

首先声明一句:JavaScript中所有函数的参数都是按值传递的!不存在按引用传递! 在讲传递参数之前我们先来讲一下指针. 学过C指针的应该都知道,指针变量中保存的是一个地址,程序可以根据所保存的地址访问内存中对应的值并进行操作,如下图: 其中地址为0x00000016保存的是一个地址,指向地址0x00000036,即0x00000016被开辟为一个指针变量,可以引用0x00000036地址的值,这是按引用方式访问变量:另外一种访问变量的方式是按值访问,即图中0x00000008地址. 在Jav

Java函数参数传递方式详解

在阅读本文之前,根据自己的经验和理解,大家可以先思考并选择一下Java函数的参数传递方式: A. 是按值传递的? B. 按引用传递的? C. 部分按值部分按引用? 此处暂不宣布正确答案,我们通过一个简单的例子让大家自己找答案: 1. 先定义一个类型Value Java代码   public static class Value { private String value = "value"; public String getValue() { return value; } pub

java中按值传递和按引用传递问题

相信对很多初学java的人来说这个问题还是很重要,因为不同于C,C++,java明确说明取消了指针,因为指针往往是再带来方便的同时也是导致代码不安全的根源,而且还会使得程序变得非常复杂和难以理解.java放弃指针只是在java语言中没有明确的指针定义,实质上,每一个new语句返回的都是一个指针的引用.只不过在大多数时候java不用关心如何操作这个"指针",更不像在操作C++的指针那样胆战心惊,唯一要多注意的是在给函数传递对象的时候.所以,初学java的人不必花费太多精力去了解,但是对于

java中参数传递方式

在 Java 应用程序中永远不会传递对象,而只传递对象引用.因此是按引用传递对象.Java应用程序按引用传递对象这一事实并不意味着 Java 应用程序按引用传递参数.参数可以是对象引用,而 Java 应用程序是按值传递对象引用的. 对象是按引用传递的: Java 应用程序有且仅有的一种参数传递机制,即按值传递: 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本: 按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本. Java 应用程

2、java 启动参数

1.java启动参数共分为三类: 其一是标准参数 (-),所有的JVM实现都必须实现这些参数的功能,而且向后兼容:其二是非标准参数 (-X),默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容:其三是非Stable参数 (-XX),此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用: 2.在使用命令java和javaw时,命令行格式如下,其中"argument"部分就可以设置一些参数. java [ options ] class [ ar

Java 可变参数

可变参数 可变参数可以当成一个数组使用 public void sum(int ...nums){ int sum = 0; for(int i:nums) { sum +=i; } System.out.println(sum); } @Test public void testSum() { sum(1,2,3,4,5); } 可变参数的实参可以是数组(同上) @Test public void testSum() { int arr[] ={1,2,3,4,5}; sum(arr); }

如何理解javaSript中函数的参数是按值传递

本文是我基于红宝书<Javascript高级程序设计>中的第四章,4.1.3传递参数小节P70,进一步理解javaSript中函数的参数,当传递的参数是对象时的传递方式. (结合资料的个人理解,有不正确的地方,希望大家指出,谢谢啦!) 参考的资料有: https://github.com/simongong/js-stackoverflow-highest-votes/blob/master/questions21-30/parameter-passed-by-value-or-referen

获取java泛型参数类型

1.Type和Class的区别 简单来说,Class实现了Type接口. Type源码定义: package java.lang.reflect; /**  * Type is the common superinterface for all types in the Java  * programming language. These include raw types, parameterized types,  * array types, type variables and pri

Full GC分析:设置Java VM参数实现在Full GC前后自动生成Dump

本文讲解了如何设置Java VM参数实现在Full GC前后自动生成Dump.共有三个VM参数需要设置: HeapDumpBeforeFullGC 实现在Full GC前dump. HeapDumpBeforeFullGC 实现在Full GC后dump. HeapDumpPath               设置Dump保存的路径 设置这些参数的方法,这里总结了四种,大家可以根据情况选择使用. 方法1: 启动jvm时,带上这些参数(这个方法适合开发测试环境) java -Xms200m -Xm

FineReport实现java报表参数查询的效果图

Java报表-参数联动与自动查询 Java报表-大数据量查询 Java报表-动态列查询 Java报表-复选框多值查询 Java报表-供应商信息模糊查询 Java报表-库存查询每页显示固定 Java报表-下拉树与动态显示查询 Java报表-自定义时间段查询 FineReport实现java报表参数查询的效果图