这是个老生常谈的问题了,引起过无数争论,但可以说一直没有一个令人满意的回答。

  有人总结过:

  1. 对象是按引用传递的
  2. Java 应用程序有且仅有的一种参数传递机制,即按值传递
  3. 按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本
  4. 按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本

  简单总结:

  1. 对象就是传引用(引用地址的拷贝,实质也是传值)
  2. 原始类型就是传值
  3. String等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。

一个小问题

  在开源中国看到这样一则问题:

https://www.oschina.net/question/2507499_2244027,其中的变量a前后的输出是什么?

  我答错了,我认为传入function的就是main函数中的a,在function中修改了a的地址,因此回到主函数后,a的地址已经变成了function中所赋予的a2的地址,因此经过function处理后a的值已经改变了。 但结果并不是,因为我忽略了Java的基础知识点之一:Java中传参都是值传递,如果是基本类型,就是对值的拷贝,如果是对象,就是对引用地址的拷贝。

基本类型的传递

  以下是处理类Porcess,代码应该已经能够自解释了。function1是将传参a变成2,function2是初始化int b,赋值为5,然后将b赋值给a:

public class Process {

    public void function1(int a) {
a = 2;
} public void function2(int a) {
int b = 5;
a = b;
}
}

我们继续看测试类TestPrimitive:

public class TestPrimitive {

    public static void main(String[] args) {
Process process = new Process();
int age = 18;
System.out.println(age);
process.function1(age);
System.out.println(age);
}
}

经过function1处理后,结果是:

18
18

修改测试类,经过function2处理后,结果是:

18
18

结论:基本类型传参,对传参进行修改,不影响原本参数的值。

对象类型传参

  以下是处理类Porcess,function3,将参数car的颜色设置成blue。function4,新建了car2,将car2赋值给了参数car。

public class Process {

    public void function3(Car car) {
car.setColor("blue");
} public void function4(Car car) {
Car car2 = new Car("black");
car = car2;
car.setColor("orange");
}
}

我们继续看测试类TestReference

public class TestReference {

    public static void main(String[] args) {
Process process = new Process();
Car car = new Car("red");
System.out.println(car);
process.function3(car);
System.out.println(car);
}
}

结果是在经过function3的处理后,输出结果是:

Car{color='red'}
Car{color='blue'}

修改测试类,在经过function4的处理后:

Car{color='red'}
Car{color='red'}

结论: 对象类型的传参,直接调用传参set方法,可以对原本参数进行修改。如果修改传参的指向地址,调用传参的set方法,无法对原本参数的值进行修改。

综上所述,基本类型的传参,在方法内部是值拷贝,有一个新的局部变量得到这个值,对这个局部变量的修改不影响原来的参数。对象类型的传参,传递的是堆上的地址,在方法内部是有一个新的局部变量得到引用地址的拷贝,对该局部变量的操作,影响的是同一块地址,因此原本的参数也会受影响,反之,若修改局部变量的引用地址,则不会对原本的参数产生任何可能的影响。

JAVA中的值传递和引用传递问题的更多相关文章

  1. Does Java pass by reference or pass by value?(Java是值传递还是引用传递) - 总结

    这个话题一直是Java程序员的一个热议话题,争论不断,但是不论是你百度搜也好还是去看官方的文档中所标明的也好,得到的都只有一个结论:Java只有值传递. 在这里就不贴代码细致解释了,让我们来看看一些论 ...

  2. Java中值传递和引用传递的概念

    很多书中都提到了在Java中只存在值传递,但是今天在一个NanoHTTPD的源码中看到这样一段: if (qmi >= 0) { decodeParms(uri.substring(qmi + ...

  3. Java中引用类型变量,对象,值类型,值传递,引用传递 区别与定义

    一.Java中什么叫做引用类型变量?引用:就是按内存地址查询       比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里new了一个Stri ...

  4. java中值传递和引用传递

    最近工作中使用到了值传递和引用传递,但是有点懵,现在看了下面的文章后清晰多了.一下是文章(网摘) 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  5. Java中的值传递和引用传递

    这几天一直再纠结这个问题,今天看了这篇文章有点思路了,这跟C++里函数参数为引用.指针还是有很大区别. 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里 ...

  6. java中方法的参数传递机制(值传递还是引用传递)

    看到一个java面试题: 问:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?  答:是值传递.Java 编程语言只有值传递参 ...

  7. Java中传参的值传递和引用传递问题(转)

    今天遇到了一个java程序,需要用参数来返回值(虽然最后用另一种方法实现了),在网上看到这样一篇文章,很受启发. 本文章来自于http://hi.baidu.com/xzhilie/blog/item ...

  8. 一道笔试题来理顺Java中的值传递和引用传递

      题目如下: private static void change(StringBuffer str11, StringBuffer str12) { str12 = str11; str11 = ...

  9. java中的值传递和引用传递有什么区别呀?

    值传递: (形式参数类型是基本数据类型和String):方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参 ...

  10. Java中的值传递与引用传递

    1.基本类型和引用类型在内存中的保存 Java中数据类型分为两大类,基本类型和对象类型.相应的,变量也有两种类型:基本类型和引用类型. 基本类型的变量保存原始值,即它代表的值就是数值本身: 而引用类型 ...

随机推荐

  1. js设计模式(二)---策略模式

    策略模式: 定义: 定义一系列的算法,把他们一个个封装起来,并且是他们可以相互替换 应用场景: 要求实现某一个功能有多种方案可以选择.比如:条条大路通罗马 实现: 场景,绩效为 S的人年终奖有 4倍工 ...

  2. 补充:MySQL经典45道题型

    一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher). 四个表的结构分别如表1-1的表(一)~表 ...

  3. 线程同步-使用ReaderWriterLockSlim类

    使用ReaderWriterLockSlim创建一个线程安全的机制,在多线程中对一个集合进行读写操作.ReaderWriterLockSlim代表了一个管理资源访问的锁,允许多个线程同时读取,以及独占 ...

  4. ng2-tree

    [转]https://github.com/valor-software/ng2-tree#eyes-demo  demo:http://valor-software.com/ng2-tree/

  5. 数据格式XML、JSON详解

    一. XML数据格式 1.1 XML的定义  扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类 ...

  6. 使用Vivado初探ZedBoard的OLED驱动

    一.原理简介 Vivado版本:2016.2 OLED型号:128*32的UG-2832HSWEG04 ZedBoard的OLED部分电路原理图如下:(需要我们关心的是我用红色椭圆标注出来的3处,一共 ...

  7. kafka8 编写简单消费者

    1.eclipse运行消费者代码.代码如下 package cn.test.mykafka; import java.util.Arrays; import java.util.Properties; ...

  8. 关于UI适配的文档

    第一部分:原理 (1)根据当前屏幕尺寸与开发预设屏幕尺寸尺寸得出以下参数. 1 XRatio:当前屏幕尺寸与开发尺寸的X轴比例 2 YRtaio:当前屏幕尺寸与开发尺寸的Y轴比例 3minRatio: ...

  9. 数据模型model设置、生成数据迁移文件、执行数据迁移文件

    一.model的配置 1.创建数据库 2.安装pymysql 3.修改配置文件 数据库连接配置 DATABASES = {'default': {'ENGINE': 'django.db.backen ...

  10. Delphi文件目录操作(转载)

    Delphi判断文件夹(目录)是否存在,不存在就创建一个,可以一次创建多级目录 procedure TForm1.Button1Click(Sender: TObject);begin if not ...