为什么说Java只有值传递?

先说一下。。以后可能不会怎么写Java相关的博客了,因为找到了字节跳动的实习工作,用Go/Python开发后端,所以这几天在抓紧时间学Go,在学Go的时候,了解到Go语言只有值传递,我突然就想起网上对Java是引用传递还是值传递有很多种说法,那么我的看法是:Java中同样只有值传递。理由且听我慢慢道来。

最简单的验证方法

其实要验证Java只有值传递有个非常简单的方法。首先我们要了解值传递和引用传递的区别是什么,其实“引用传递”这个词,在C++语言中听到得最多,在值传递中,实参是传入对象的一份拷贝,因此对参数的修改不会影响传入的对象。而在引用传递中,传递的是对象的一个别名,若创建引用后,原对象的地址发生改变,引用的对象依然不会改变,而这种机制目前我只在C++语言中听说过。(主要还是学过的编程语言太少)

这种机制甚至在C语言中都没有,那么C语言要通过函数去改变一个参数该怎么办呢?正确的做法是指针传递

void swap(int *a,int *b)
{
    int temp;
    temp = *a
    *a = *b;
    *b = temp;
}

指针传递可以改变传入的参数,那么它是引用传递吗?并不是,它只是传递了指针的值,而函数内部因为获取了指针的值,于是可以通过指针获取指向的对象,从而修改它。

指针传递在C++中也可以使用,而C++要实现同样的功能还可以使用引用传递:

void swap(int& a, int& b)
{
    int swap = a;
    a = b;
    b = swap;
}

那么这两种方法有什么区别呢?区别就是,在指针传递的方法中,改变指针的值,外部并不会变化。

例如下面这段代码(引用传递)输出10,引用发生改变:

而下面这段代码(指针传递)则还是输出5,因为外部的指针不会随之发生改变:

那么,通过这两个示例,我们就可以写出一段Java代码来验证一下Java中是引用传递还是值传递:

既然网上很多资料说,Java除了基本类型,都是引用传递,那么我们这里就写了一个类进行测试,在函数内部去修改了一下获取的参数。

你可以尝试运行这段代码,输出的结果仍是:TestObject{value=1},说明它和C++中的指针传递的机制是一样的。这也是为什么我认为Java中都是值传递的原因。

Java中不是没有指针吗?

Java只是对使用者封装了指针的概念,我们看下面这行代码:

Object o = new Object();

new Object()实际上是在堆上创建了一个对象,o这个局部变量,是分配在栈上的,一个八字节的引用(reference)类型,指向堆上的对象

所以可以认为o就是一个指针,具体的机制在深入理解java虚拟机第三版读书笔记03--1.3 对象的访问定位中也有提到,HotSpot使用的对象访问定位的方式是直接指针访问,栈上的reference数据存储的就是对象在堆中的地址。

因此我倾向于认为,Java的这种传参方式,类似于C++中的指针传递,并没有引用传递的概念,因此可以说,Java中只有值传递。

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/%e4%b8%ba%e4%bb%80%e4%b9%88%e8%af%b4java%e5%8f%aa%e6%9c%89%e5%80%bc%e4%bc%a0%e9%80%92%ef%bc%9f/

(0)
彭晨涛彭晨涛管理者
上一篇 2020年6月21日
下一篇 2022年4月13日

相关推荐

  • CountDownLatch及CyclicBarrier源码分析

    之前写的一篇博客JUC包下的线程协作计数CountDownLatch及CyclicBarrier只是介绍了一下这两个工具类的用法,并没有深入探究源码,然而实现方法也比较简单,所以合…

    Java 2020年5月22日
    0140
  • 深入理解java虚拟机第三版读书笔记11

    以下是第十一章 后端编译与优化的内容 把Class文件转换成与本地基础设施(硬件指令集、操作系统)相关的二进制机器码可以视为整个编译过程的后端。 最近几年提前编译也开始兴起,我们在…

    2020年1月27日
    0270
  • NIO网络编程之Selector介绍

    Selector 要实现异步IO要通过Selector,甚至我们可以通过一个线程管理多个Channel的读写,这是NIO相较BIO的优越之处之一。 Channel可以注册到一个Se…

    Java 2020年2月7日
    0750
  • 网络编程之AIO

    AIO介绍 AIO是JDK1.7引入的,也称为NIO 2.0 NIO的同步非阻塞类似于轮询,让Selector去询问各个通道的状态。 而AIO则是通过Future实现真正的异步,让…

    Java 2020年2月8日
    0280
  • Collection接口研究

    以下内容基于jdk1.8 接口Collection分析 img 该接口实现了接口Iterable 方法: int size(); 返回元素的个数 boolean isEmpty()…

    2019年11月13日
    090
  • Java基础查缺补漏01

    某些点会在不远的将来深挖。 >>是逻辑右移,>>>是算术右移 JDK6 可以使用Console.readPassword从控制台中读取密码,用户输入的过程中密码是不可见的。…

    2019年11月26日
    0590
  • 谈一谈StringBuffer、StringBuilder及String在JDK9中的变化

    本文参考资源: JAVA9 String新特性,说说你不知道的东西Java人在江湖-CSDN博客 StringBuffer和StringBuilder的区别 这里谈的是JDK8中S…

    2020年4月9日
    0340
  • 操作系统五种IO模型介绍

    本文参考资源: 五种IO模型详解IO模型,java小范的博客-CSDN博客 阻塞 IO 模型 最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求…

    计算机相关 2020年2月12日
    0700
  • 深入理解java虚拟机第三版读书笔记06

    附: Java虚拟机规范-Class文件格式:JDK8 Java虚拟机规范-Class文件格式:JDK13 以下是第六章 类文件结构的内容 Class类文件的结构 Class文件是…

    Java 2020年1月18日
    0160
  • HashMap源码分析

    HashMap是java中非常常见的一个数据结构,在这篇文章里,我依然以Map中的操作为导向来循序渐进研究HashMap中的源码,阅读这篇文章需要的前置知识有: 弱平衡的二叉查找树…

    Java 2020年2月12日
    0220

发表回复

登录后才能评论