一、前言

  首先先说结论,Java中方法参数传递方式是按值传递。如果参数是基本类型,传递的是基本类型的字面量值的拷贝。如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。

  接下来深入了解一下为什么是值传递,要想知道Java到底是传值还是传引用,首先要知道基本类型和引用类型的区别。

二、深入了解参数传递

  1.基本类型 和 引用类型的不同之处

基本类型包括8种数据类型:int、short、long、byte、char、float、double、boolean,在方法中定义的非全局基本数据类型变量的具体内容是存储在栈中的;除了基本类型以外的都是引用类型:类、接口类型、数组类型、字符串类型都是引用类型,引用类型变量其具体内容都是存放在堆中的,而栈中存放的是其具体内容所在内存的地址(字符串类型比较特殊,涉及到字符串常量池,这里不做深入研究)。

示例:

int num = 10;      
String str = new String("hello");

注:该图的堆区是经过简化的,实际的情况会复杂点,这里只作示意

如图所示,num是基本类型,值就直接保存在变量中。而str是引用类型,变量中保存的只是实际对象的地址。一般称这种变量为"引用",引用指向实际对象,实际对象在堆中并保存着实际内容。

  2.赋值运算符(=)的作用

num = 20;
str = "world";
注:该图的堆区是经过简化的,实际的情况会复杂点,这里只作示意
 
对于基本类型 num ,赋值运算符会直接改变变量的值,原来的值被覆盖掉。
对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变。如上图所示,"world" 字符串对象没有被改变。(没有被任何引用所指向的对象是垃圾,会被垃圾回收器回收)。
  3.值传递和引用传递的区别
值传递是指在调用函数时将实际参数复制一份传递到函数中,引用传递是指在调用函数时将实际参数的地址直接传递到函数中,所以值传递和引用传递的根本区别是是否会复制一份副本。
  4.实例
  例子一(基本数据类型):  
public static void main(String[] args) {
Test test = new Test(); int i = 10;
test.print(10);
System.out.println("main方法输出i:" + i);
} public void print(int j) {
j = 20;
System.out.println("print方法输出j:" + j);
}

  结果:

print方法输出j:20
main方法输出i:10

这个例子应该还是很好理解的,test.print(10)将10作为参数传给print方法, 将10拷贝一份给 j,修改 j 不会影响 i 。

  例子二(引用数据类型):

public static void main(String[] args) {
Test test = new Test();
User user = new User();
user.setName("Tom");
user.setAge("18");
test.print(user);
System.out.println("main方法输出用户:" + user);
} public void print(User user1) {
user1.setName("Mike");
System.out.println("print方法输出用户:" + user1);
}

  结果:

print方法输出用户:User{name="Mike",age="18"}
main方法输出用户:User{name="Mike",age="18"}

  解释: test.print(user)将user对象的引用(即user对象的内存地址)拷贝一份给形参的user1,也就是说main方法中的user引用和print方法的user1引用都指向堆中的同一个user对象,所以user1修改user对象的数据,user的也会相应的改变。

  user1.setName("Mike")执行前

  user1.setName("Mike")执行后

注意:引用数据类型中的字符串类型比较特殊,String被设计成为了不可变类型,为String赋值时不会覆盖以前的对象而是引用一个新的字符串对象(如果新的字符串在常量池中直接返回其引用,否则创建一个字符串对象,详情可以去我的另一篇博客浅析Java常量池 - pluto_blog - 博客园 (cnblogs.com)),在这里我们不考虑新字符串在常量池的情况。

  下面来看各String类型的例子:
public static void main(String[] args) {
Test test = new Test();
String name = new String("Tom");
test.print(name);
System.out.println("main方法输出name:" + name);
} public void print(String name1) {
name1 = "Mike";
System.out.println("print方法输出name1:" + name1);
}

  结果:

print方法输出name1:Mike
main方法输出name:Tom

  解释:由于String被设计成为了不可变类型,为name赋值时不会覆盖以前的对象而是创建一个新的字符串对象并返回引用。

  name1 = "Mike"执行前

  name1 = "Mike"执行后

三、总结

Java中方法参数传递方式是按值传递。如果参数是基本类型,传递的是基本类型的数据拷贝。如果参数是引用类型,因为栈中存的是对象的地址值,所以传递的是该参量所引用的对象在堆中地址值的拷贝,除了特殊的String类型,形参对象可以影响实参对象的值。

Java的参数传递是值传递还是引用传递?的更多相关文章

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

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

  2. java参数传递时到底是值传递还是引用传递

    java参数传递时到底是值传递还是引用传递(baidu搜集) 问”,很多人的BLOG里都引用这些面试题,最近因为工作内容比较枯燥,也来看看这些试题以调节一下口味,其中有一道题让我很费解. 原题是:当一 ...

  3. java中参数传递--值传递,引用传递

    java中的参数传递——值传递.引用传递   参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递. 在 Java 应用程序中永远不会传递对象,而只传递对象引用. ...

  4. Java参数传递是值传递还是引用传递?

    当一个对象被当作参数传递到一个方法后,在此方法内可以改变这个对象的属性,那么这里到底是值传递还是引用传递? 答:是值传递.Java 语言的参数传递只有值传递.当一个实例对象作为参数被传递到方法中时,参 ...

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

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

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

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

  7. JavaScript 函数参数传递到底是值传递还是引用传递

    tips:这篇文章是听了四脚猫的js课程后查的,深入的理解可以参看两篇博客: JavaScript数据类型--值类型和引用类型 JavaScript数据操作--原始值和引用值的操作本质 在传统的观念里 ...

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

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

  9. Java是值传递还是引用传递?

    Java的值传递和引用传递在面试中一般都会都被涉及到,今天我们就来聊聊这个问题.这个问题一般是相对函数而言的,也就是Java中所说的方法参数,那么我们先来回顾一下在程序设计语言中有关参数传递给方法的两 ...

随机推荐

  1. SignalR的客户端.NET Client介绍

    SignalR支持两种客户端:JavaScript Client和.NET Client.一个简单的SignalR例子中的SignalRDemo(点赞页面)就是JavaScript Client(HT ...

  2. 大数据学习(17)—— HBase表设计

    为啥要把表设计拿出来独立成章?因为我觉得像我这样搞了很多年Java后端开发的技术人员,在学习HBase的时候,会受到关系型数据库3NF.BCNF的影响.事实上,数据库范式在HBase里完全没用,必须转 ...

  3. 网安日记③之通过iis搭建ftp并使用通过serv-u搭建ftp

    通过iis搭建ftp并使用通过serv-u搭建ftp 安装iis的ftp访问 由于在安装iis时勾选了ftp服务,我们直接在iis界面右键ftp服务打开属性查看本地路径 在电脑目录下打开安装目录,并在 ...

  4. AlarmManager定时提醒的那些坑

    https://blog.csdn.net/zackratos/article/details/53243595 https://blog.csdn.net/bingshushu/article/de ...

  5. 大厂Android岗高频面试问题:说说你对Zygote的理解!

    前言 Zygote可以说是Android开发面试很高频的一道问题,但总有小伙伴在回答这道问题总不能让面试满意, 在这你就要搞清楚面试问你对Zygote的理解时,面试官最想听到的和其实想问的应该是哪些? ...

  6. web笔记随笔

    1.Web服务组件 8.第三方内容:广告统计.mockup 7.Web前端框架: HTML5. jQuery. Bootstrap 6.Web应用: CMS. BBS. Blog 5.Web开发框架: ...

  7. HCIA—(网络初相识)

    网络 IT--> 信息服务 -->数据底层 云计算 大数据 CT--> 通信服务 -->通信服务 构建数据通信的协议 ICT-->信息通信 数据 + 通信 数通 基础 R ...

  8. 优秀Android开发简历都是这么写,你学会也可以进大厂

    最近收了很多程序员的简历,工作经验从1年到十几年不等.发现一个问题,工作经验范围差不多的程序员,简历看起来也差不多... 为啥程序员的简历如此统一?正好最近看到一个分享也分析了这个问题,结合我个人的一 ...

  9. 2020互联网寒冬之下,作为一个Android老码农,是如何进入腾讯的?

    由于众所周知的原因,原生Android开发如今已经日渐凋敝,作为一个Android程序员,不仅要会Java,Kotlin,JavaScript,Css,Html,还要会Flutter,C++,FFmp ...

  10. 二、Windows安装与简单使用MinIO

    MinIO的官方网站非常详细,以下只是本人学习过程的整理 一.MinIO的基本概念 二.Windows安装与简单使用MinIO 三.Linux部署MinIO分布式集群 四.C#简单操作MinIO 一. ...