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

  有人总结过:

  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. String字面量

    public class assa{ static String ee = "aa";//ee指向常量池中的aa static String ff = new String(&qu ...

  2. fiddler的一些记录

    通过execaction.exe可以给fiddler发命令,控制抓包开始和停止 https://stackoverflow.com/questions/29916508/start-and-stop- ...

  3. Jedis 连接池实例

    package com.java56.redis; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; im ...

  4. keepalived实现高可用

    准备: 1.A-centos(192.168.6.177)  端口为9898的服务 2.B-ubuntu(192.168.6.182)  端口为9898的服务 3.keepalived安装包https ...

  5. Jenkins+Jmeter持续集成笔记(二:ANT执行Jmeter脚本)

    Jmeter接口测试脚本运行后生成的是jtl(xml)格式的文件,这些文件不具备可读性,所以我们要把他转化为可以阅读的html格式报告. Ant是一个功能强大的打包编译工具.我们使用他的目的是将xml ...

  6. javaweb(2)之Servlet入门

    Hello Servlet 方式一 1.新建 web 工程,编写一个类,实现 javax.servlet.Servlet 接口: package com.zze.servlet; import jav ...

  7. Java作业(一)

    再此次的Java考试中发现自己的不足,无法套用HTML模板进行编程,说实话拿到的第一刻自己有些懵,不知道怎么去操作, 后来通过查询操作了一些,但是整个人还是懵懵的,不知道下一步怎么办,怎么去连接后台和 ...

  8. Go 初体验 - 令人惊叹的语法 - defer.4 - defer 对宿主函数返回值的影响

    defer 函数可以影响宿主函数的返回值 看代码: 调用: 输出: 结果又让人意外了. coo1:因为传引用,return 时 i = 100, return 返回的也是 100,return 执行之 ...

  9. Selenium上机实验

    1.安装SeleniumIDE插件 2.学会使用SeleniumIDE录制脚本和导出脚本 3.访问https://psych.liebes.top/st使用学号登录系统(账户名为学号,密码为学号后6位 ...

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

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