每日一道Java面试题:Java是值传递还是引用传递?

简介: 每日一道Java面试题:Java是值传递还是引用传递?

写在开头

Java是值传递还是引用传递?这个问题几乎100%的出现在了各大主流Java面试题中,知识点很小,但很考验面试者对于Java运行的理解,今晚趁着生产投产的空子,过来小聊一下。

实参与形参

所谓的值传递or引用传递是指方法在调用的过程中实参传递的两种变现形式,那么好,想搞清楚这个问题的前提是,先搞清楚实参形参

实际参数(实参,英文:Arguments):用于传递给函数/方法的参数,必须有确定的值!
形式参数(形参,英文:Parameters):用于定义函数/方法,接收实参,不需要有确定的值。

int a = 10;
//这里传入的a为实参,有实际确认的值:10
sum(a);
//这里方法定义中的参数为形参,无需确认值,在方法调用中用来接收实际参数
void sum(int p){
   
   
    System.out.println(p+10);
}

值传递与引用传递

为了充分调用大家的思考,这里先不给结论,先上几段代码示例,通过分析代码,最终得出结果,这是个人最喜欢的总结方式!

【代码示例1-基本数据类型的参数传递】

public class Test {
   
   
    public static void main(String[] args) {
   
   
        int a = 1;
        int b = 2;
        swap(a, b);
        System.out.println("实参a = " + a);
        System.out.println("实参b = " + b);
    }
    public static void swap(int p1, int p2) {
   
   
        int temp = p1;
        p1 = p2;
        p2 = temp;
        System.out.println("p1 = " + p1);
        System.out.println("p2 = " + p2);
    }
}

输出:

p1 = 2
p2 = 1
实参a = 1
实参b = 2

分析:
在swap()方法中,我们将p1,p2参数的值进行了互换,但这并没有影响实参a,b的值,因为在传入方法时,只是对a,b的值做了拷贝,拷贝之后,他们之间的关系互相独立,这就是值传递!

【代码示例2-引用类型的参数传递】

public class Test {
   
   
    public static void main(String[] args) {
   
   
        int[] arr = {
   
    1, 2, 3};
        System.out.println(arr[0]);
        change(arr);
        System.out.println(arr[0]);
    }
    public static void change(int[] array) {
   
   
        array[0] = 0;
    }
}

输出:

1
0

分析:
初始化一个引用类型的数组arr作为实参,在change方法中我们将数组的0位数值进行了重新赋值,将实参传入方法执行后,我们可以看到实参的第0位数值已经被成功修改为0,看上去是不是像引用传递?
实则不然!请看下面的示意图:

image.png

我们知道实参arr是一个对象的引用,而在调用change()时将实参传进来,其实是拷贝了一份实参的引用地址过来,而这个时候实现与形参,他们会执行对象数据对象的同一个地址,导致我们在修改形参的数组值时,实参的0位数值也发生了改变,毕竟他们指向的是同一对象!

【代码示例3-String的参数传递】

public class Test{
   
   
    public static void main(String[] args) {
   
   
        Test test= new Test();
        // String类
        String s = "hello";
        test.pass(s);
        System.out.println("s = " + s);
    }
    public void pass(String str) {
   
   
        str = "world";
        System.out.println("str = "+ str);
    }
}

输出:

str = world
s = hello

分析:
看到这个结果时,是不是有点出乎意料,在示例2中我们得知,引用类型时的参数传递,拷贝的是引用地址的值,实参会随着形参的改变而改变,但这一段代码的输出显然不符合预期,这是为什么?
看过俺之前写的文章的朋友应该是清楚的,虽然String也是引用类型,但它是不可变类,一旦对赋值完成,就改变不聊了,这也就意味着,上述代码中的两次字符串赋值,分别操作的是两个String对象,两者毫无关联!

总结

看完了如上的例子,大家对Java的参数传递有没有更深的了解了呢,通过上面的几个例子我们可以得出这样的总结:

Java中将实参传递给方法(或函数)的方式是值传递
如果参数是基本类型的话,很简单,传递的就是基本类型的字面量值的拷贝,会创建副本。
如果参数是引用类型,传递的就是实参所引用的对象在堆中地址值的拷贝,同样也会创建副本。

目录
相关文章
|
29天前
|
缓存 Java 关系型数据库
【Java面试题汇总】ElasticSearch篇(2023版)
倒排索引、MySQL和ES一致性、ES近实时、ES集群的节点、分片、搭建、脑裂、调优。
【Java面试题汇总】ElasticSearch篇(2023版)
|
29天前
|
设计模式 Java 关系型数据库
【Java笔记+踩坑汇总】Java基础+JavaWeb+SSM+SpringBoot+SpringCloud+瑞吉外卖/谷粒商城/学成在线+设计模式+面试题汇总+性能调优/架构设计+源码解析
本文是“Java学习路线”专栏的导航文章,目标是为Java初学者和初中高级工程师提供一套完整的Java学习路线。
237 37
|
29天前
|
存储 缓存 NoSQL
【Java面试题汇总】Redis篇(2023版)
Redis的数据类型、zset底层实现、持久化策略、分布式锁、缓存穿透、击穿、雪崩的区别、双写一致性、主从同步机制、单线程架构、高可用、缓存淘汰策略、Redis事务是否满足ACID、如何排查Redis中的慢查询
【Java面试题汇总】Redis篇(2023版)
|
4天前
|
缓存 安全 Java
三万字长文Java面试题——基础篇(注:该篇博客将会一直维护 最新维护时间:2024年9月18日)
本文是一篇全面的Java面试题指南,涵盖了Java基础、数据类型、面向对象、异常处理、IO流、反射、代理模式、泛型、枚举、Lambda表达式、Stream流等多个方面的知识点,并提供了详细的解析和代码示例。
19 0
三万字长文Java面试题——基础篇(注:该篇博客将会一直维护 最新维护时间:2024年9月18日)
|
29天前
|
设计模式 安全 算法
【Java面试题汇总】设计模式篇(2023版)
谈谈你对设计模式的理解、七大原则、单例模式、工厂模式、代理模式、模板模式、观察者模式、JDK中用到的设计模式、Spring中用到的设计模式
【Java面试题汇总】设计模式篇(2023版)
|
29天前
|
存储 关系型数据库 MySQL
【Java面试题汇总】MySQL数据库篇(2023版)
聚簇索引和非聚簇索引、索引的底层数据结构、B树和B+树、MySQL为什么不用红黑树而用B+树、数据库引擎有哪些、InnoDB的MVCC、乐观锁和悲观锁、ACID、事务隔离级别、MySQL主从同步、MySQL调优
【Java面试题汇总】MySQL数据库篇(2023版)
|
29天前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
29天前
|
缓存 Java 数据库
【Java面试题汇总】Spring篇(2023版)
IoC、DI、aop、事务、为什么不建议@Transactional、事务传播级别、@Autowired和@Resource注解的区别、BeanFactory和FactoryBean的区别、Bean的作用域,以及默认的作用域、Bean的生命周期、循环依赖、三级缓存、
【Java面试题汇总】Spring篇(2023版)
|
29天前
|
存储 缓存 监控
【Java面试题汇总】JVM篇(2023版)
JVM内存模型、双亲委派模型、类加载机制、内存溢出、垃圾回收机制、内存泄漏、垃圾回收流程、垃圾回收器、G1、CMS、JVM调优
【Java面试题汇总】JVM篇(2023版)
|
29天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)

热门文章

最新文章