【Java】Java中的“引用类型”和C中的“指针”区别

2023-11-07

前言

在学习Java中变量的数据类型时,发现其分为2大类:基本数据类型、引用数据类型。

其中,属于“引用数据类型”的有:String、数组、类、接口。

相比C语言,Java中的“引用数据类型”,和C语言中的“指针”比较相似,所以这里将两者进行对比分析。

1. Java中“基本数据类型”和“引用数据类型”变量在内存分配时的不同

  • 对于“基本数据类型”的变量:当你定义变量int i = 0; 那么它在内存里的分配是这样的:内存里分配了一块空间,这块空间的名字是i,里面的内容是0。当你使用i的时候就可以访问这块空间里的内容。
  • 对于“引用数据类型”的变量:引用类型的变量,在内存分配时,会分配两块内存,一块存储引用,一块存储。进一步,如果是通过new来创建引用变量,则两块内存分别是栈(来存储引用变量)和堆(来存储引用变量所指向的值);如果不用new,则两块内存都在栈中。

例如:
不同方式定义字符串时堆和栈的变化:(参考:深入解析Java new运算符

public class Test {
    public static void main(String[] args) {
        String a = "C语言中文网";
        String b = new String("C语言中文网");
        String c = "C语言中文网";
        String d = new String("C语言中文网");
        System.out.println(a == b);
        System.out.println(a == c);
        System.out.println(d == b);
        System.out.println(a);
        a = "Java";
        System.out.println(a);
    }
}

输出结果:

false
true
false
C语言中文网
Java

解析:

  • String a;只是在栈中创建了一个 String 类的对象引用变量 a。
  • String a = "C语言中文网";在栈中创建一个 String 类的对象引用变量 a,然后查找栈中有没有存放“C语言中文网”,如果有则直接指向“C语言中文网",如果没有,则将”C语言中文网“存放进栈,再指向。
  • String a = new String("C语言中文网");不仅在栈中创建一个 String 类的对象引用变量 a,同时也在堆中开辟一块空间存放新建的 String 对象“C语言中文网”,变量 a 指向堆中的新建的 String 对象”C语言中文网“

==用来比较两个对象在堆区存放的地址是否相同。根据上面的输出结果,我们可以看出:

  • 使用 new 运算符创建的 String 对象进行==操作时,两个地址是不同的。这就说明,每次对象进行 new 操作后,系统都为我们开辟堆区空间,虽然值是一样,但是地址却是不一样的。所以第三个输出为false。
  • 当我们没有使用 new 运算符的时候,系统会默认将这个变量保存在内存的栈区。如果变量的值存放在栈中,使用==比较时,比较的是具体的值。如果变量的值存放在堆中,使用==比较时,比较的是值所在的地址。因此在变量 a 与变量 c 进行==操作的时候,返回 true,因为变量 a 和变量 c 比较的是具体的值,即“C语言中文网”。
  • 在改变引用变量 a 的值后(如 a = “Java”),再次输出时,我们发现输出的结果是”Java“。事实上原来的那个“C语言中文网”在内存中并没有清除掉,而是在栈区的地址发生了改变,这次指向的是”Java“所在的地址。
  • 如果需要比较两个使用 new 创建的对象具体的值,则需要通过“equal()”方法去实现,这样才是比较引用类型变量具体值的正确方式。

2. C中“指针”的特点

  • C语言的指针可以指向内存的任何地方。
  • C语言的指针可以参与数值运算,加法、减法。
  • C语言的指针还可以指向指针,以及指向“指向指针”的指针(因为指针本身也是一个变量,也要存在内存中,所以它也有一个内存地址)
  • 指针,只关心其所指向内存的地址,不关心内存存的是什么东西,如果该地址中的数据被搬走了,指针不会自动改变指向。

3. Java中“引用”的特点

  • java的引用是某个值所在内存地址其关注的是对应值的本身,而不是该值在内存中的地址当值搬家后,引用也会自动跟着改。(这一点和指针不同)
  • java的引用,声明一个引用变量时(不赋值),不占空间。
  • java的引用初始值为 NULL。(C中指针的值如果不初始化,其值不确定,会变为野指针,很危险)
  • java的引用本身不可以参与计算。(C的指针的数据类型是int,其可以参与计算,如++或–,所以经常用指针来代替数组下标)

4. Java的参数传递

java的方法在传递参数时,一般有两种情况:

  • 参数是基本数据类型,就直接将基本类型的值传递过来。
  • 参数是引用数据类型,将参数的引用值copy一份传递过来。

所以可以说java只有值传递,所谓的引用传递,传递的是引用的值。

5.参考

java中的引用与c中的指针

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Java】Java中的“引用类型”和C中的“指针”区别 的相关文章

  • 如何正确地将MapStruct与Eclipse集成? (包括Lombok java代理)

    我愿意在一些官方项目中使用MapStruct 所以我决定先对其进行一些测试 我需要让它与 eclipse 集成工作 并遵循 MapStruct 网站上提供的所有说明 但是 到目前为止还没有运气 有人成功实现了这种整合吗 如果是的话我可以缺少
  • 如何在 NetBeans 中以调试模式单步执行已实现的方法?

    我有课XImpl java它实现了一个接口X java 以及所有它的方法 我调试项目 在执行流程中遇到一个方法X processSomeValue 现在 当我尝试进入该方法时processSomeValue 我无能为力 有什么办法可以让我进
  • 如何为Spring Boot中的所有控制器指定前缀?

    我有控制器映射到 user and order RestController RequestMapping users public class UserController RestController RequestMapping or
  • 如何在异常处理程序中访问访问请求主体

    我们有一个 Spring Boot 应用程序 我们的控制器期望在我们的端点之一中有一个 XML 文档元素 PostMapping value api v1 do stuff consumes APPLICATION XML VALUE pr
  • 使用 Bouncy Castle 重建 ED25519 按键 (Java)

    Bouncy Castle 的最新 测试版 版本 bcprov jdk15on 161b20 jar 支持 ED25519 和 ED448 EC 加密以进行签名 我设置了这个完整的工作示例 它按预期工作 我的问题 我是否正确重建了私钥和公钥
  • Junit测试中LocalDateTime反序列化的问题

    我有问题LocalDateTime反序列化Junit测试 我有简单的REST API返回一些DTO目的 当我呼叫端点时 响应没有问题 它是正确的 然后我尝试编写单元测试 得到MvcResult并使用ObjectMapper将其转换为我的DT
  • Java OR 运算符优先级

    如何在 Java 中以 if 的方式链接条件语句b是假的 不如不检查c If a and c是假的 并且b是真的 确实c会被检查吗 if a b c 我正在寻找 PHP 所拥有的类似功能 但两者之间存在差异OR and 爪哇 如果左操作数是
  • 写入作为 Jar 文件中的资源包含的 Java 属性文件

    有没有办法修改作为资源存储在 Jar 文件中的属性文件中的属性值 这就是我正在尝试处理的场景 我有一个属性文件作为资源存储在我的 Jar 文件中 有一些系统特定的属性 例如路径 我希望能够为我想要运行 Jar 文件的系统更改此设置 最好的解
  • Java Sound可以用来控制系统音量吗?

    Java 声音优惠FloatControl各种声音线路功能的实例 以及MASTER GAIN http docs oracle com javase 7 docs api javax sound sampled FloatControl T
  • 注释处理器可以用于代码生成吗?

    假设我定义了一个名为 MyAnnotation 有一个班级X其声明为 MyAnnotation class X 现在在编译时我想检查所有带有注释的类 MyAnnotation并对更多需要在同一进程中编译的 java 源文件进行一些代码生成
  • Spring Security登录返回404

    我目前正在使用 Spring 框架开发我的博客 我正在实现 Spring Security 用于登录目的 一切都按预期进行 直到我提交始终返回 404 代码的登录凭据 这是我的 web xml 代码e
  • 一起使用 String 和 int 时的 System.out.println 行为 [重复]

    这个问题在这里已经有答案了 考虑下面的代码片段 public class Student public static void main String args int a 3 int b 4 System out println a b
  • 公共领域有哪些替代方案?

    我正在用 java 编写一个游戏 正如问题标题建议的那样 我在类中使用公共字段 暂且 据我所知 公共领域很糟糕 我有一些理解其中的原因 但如果有人能澄清为什么你不应该使用它们 那将不胜感激 问题是 从我所看到的来看 这似乎是合乎逻辑的 是使
  • Java文本输出中的UTF-8编码问题

    我一直致力于测试高棉语 Unicode Wordbreaker 的各种解决方案 高棉语单词之间没有空格 这使得拼写检查和语法检查变得困难 以及从旧高棉语转换为高棉语 Unicode 我得到了一些源代码 现在在线 http www white
  • 如何在 Struts 2 中访问 OGNL 跟踪评估?

    有人告诉我要优化网络应用程序 为此 我使用JProfiler https www ej technologies com products jprofiler overview html 我注意到很大一部分响应时间都花在了表示层上 特别是当
  • 在 Struts 2 中使用单个文件标签上传多个文件

    我想使用单个 Struts 2 文件标签上传多个文件 就像在 Gmail 中一样 我们使用 CTRL 键来选择多个文件来附加多个文件 我知道如何上传多个文件 但我想使用单个文件标签 我在一个小画廊应用程序中上传多个文件 如果您的操作已设置为
  • 如何找到 JAR:/home/hadoop/contrib/streaming/hadoop-streaming.jar

    我正在练习有关 Amazon EMR 的复数视角视频教程 我被困住了 因为我收到此错误而无法继续 Not a valid JAR home hadoop contrib streaming hadoop streaming jar 请注意
  • 尝试接收 UDP 多播时出现空指针异常

    在尝试了几次让简单的 UDP 多播接收器工作后 我感到很困惑 在我自己的代码无法按预期工作后 我尝试了 vertx 文档中发布的确切示例 DatagramSocket socket vertx createDatagramSocket ne
  • 在Java中将32bpp图像转换为16bpp图像

    如何使用 Java 库将 32bpp 图像 ARGB 转换为 16bpp 图像 ARGB 出于我的好奇 在像素级别 这种转换有什么作用 如果我有一个保存像素值 包含所有通道 的 int 值 那么在转换发生后该 int 会有什么不同 32 位
  • 如何在Java中添加两个“卡”的值?

    我正在开发一个项目来模拟二十一点游戏中的第一笔交易 到目前为止 程序创建了两张随机等级 ACE 到 KING 和随机花色的牌 我正在努力创建一个切换表或 if else 梯形图 将两张卡的附加值分配为可变分数 下面的代码从概念上代表了我想要

随机推荐

  • 数据挖掘学习(二)——数据探索与清洗

    笔者是一个痴迷于挖掘数据中的价值的学习人 希望在平日的工作学习中 挖掘数据的价值 找寻数据的秘密 笔者认为 数据的价值不仅仅只体现在企业中 个人也可以体会到数据的魅力 用技术力量探索行为密码 让大数据助跑每一个人 欢迎直筒们关注我的公众号
  • 我遇到的BUG:WSL2 忘记用户密码

    我之前忘记了WSL的密码 在网上看了很多瞎写的博文 没起到作用 后来偶然看到一篇文章 解决了这个问题 要在WSL中重置用户密码 需要 在windows命令行里将默认用户切换为root 在WSL里重置用户密码 在windows命令行里将默认用
  • sqlServer数据库索引

    08 索引 8 1 定义 对数据库表中一个或者多个列进行排序的结构 有助于更快的获取信息 是用来获取定位的 8 2 作用 加快数据检索 保证数据的一致性 实现表与表之前的参照完整性 副作用 创建索引会占用空间并耗费一定的时间 创建索引会减慢
  • 【可解释性机器学习】interpretable machine learning——Functional Decomposition

    Functional Decomposition 机器学习中的监督学习模型可被视为一个函数 该函数将高维特征向量作为输入 然后产生预测或分类概率作为输出 函数分解 functional decomposition 分解高维函数并将其表达为可
  • 常见前端安全问题概述

    随着互联网的高速发展 安全问题已成为企业最关注的焦点之一 而前端又是容易引发安全问题的 窗口 作为开发人员的我们 更需要充分了解如何预防和修复安全漏洞 本文将列举常见的前端安全问题 希望对你有所帮助 本文将从以下几种安全问题展开介绍 XSS
  • Jmeter中csvRead函数的使用

    当想要脚本随机传参数时 可以结合csvRead和Random函数使用 也相当于参数化的一种用法 想了解其他参数化方法的读者 可以参考上一篇文档 1 事先准备好存储数据的文档 注意 数据之间使用英文逗号隔开 否则后面随机抽取数据时没有抽取到
  • 【yarn】yarn Job 状态机正常执行流程

    1 概述 今天6月1日 节日值得发个文章 庆祝一下 上一篇文章 Yarn Yarn Service端如何处理客户端提交的任务 在上一篇文章中 我们知道服务器接收到客户端提交的任务之后 会启动多个状态机进行联合操作 最终来解决任务提交之后的全
  • JS内置对象Math的常用方法

    JS内置对象Math的常用方法 1 向上取整 Math ceil 2 向下取整 Math floor 3 四舍五入 Math round 4 绝对值 Math abs 最大值 Math max 最小值 Math min 7 随机数 Math
  • 5 种方法重复执行历史命令

    Linux 下 如果要执行一条或多条之前输过的指令 要怎么处理 很多人会想到使用上下箭头去翻查历史输入的命令 这当然是可以了 除了这种方法 本文再介绍另外 5 种方法来实现这样的效果 在正式开始之前 我们先随便执行几条命令 便于后面演示 为
  • Anaconda 更换镜像源、创建虚拟环境并安装 PyTorch

    文章目录 1 更换镜像源 2 选择合适的 CUDA Runtime 版本 2 1 CUDA Runtime 版本不能高于 CUDA Driver 版本 2 2 根据显卡的算力和架构确定 CUDA Runtime 版本 2 3 找到安装 Py
  • Ps2021软件安装Mac(含M1)、Windows版

    一 下载链接 Mac版本 1 M1芯片适用 百度网盘下载地址 提取码 rpyn 2 M1不适用 系统10 15及以上 下载地址 Windows版本 Ps2022 64位 此版本不支持LTSC版本系统 百度网盘下载地址 提取码 wb2d 二
  • MySQL: 运算符使用练习

    前言 练习运算符的使用 加强记忆 案例目的 在已建数据库中创建数据表 并对表中数据进行处理 练习运算符 包括数据运算符 逻辑运算符 位运算符 的使用 操作过程 创建名为 tb15 的数据表 包含 VARCHAR 100 类型的字段 note
  • 在vue中使用this.$refs报错undefined找不到子组件的方法

    最近遇见个问题 在父组件调用子组件的方法时报错undefined 这种情况一般都是父组件调用子组件方法的时候 dom还没更新成功 可以使用 this nextTick 这个方法作用是当数据被修改后使用这个方法会回调获取更新后的dom再渲染出
  • Spring MVC视图解析器

    Spring MVC视图解析器 AbstractCachingViewResolver XmlViewResolver ResourceBundleViewResolver UrlBasedViewResolver InternalReso
  • 报错Caused by java lang ClassNotFoundException Didn't find c

    分享一下我老师大神的人工智能教程 零基础 通俗易懂 风趣幽默 还带黄段子 希望你也加入到我们人工智能的队伍中来 https blog csdn net jiangjunshow 报错信息 03 14 20 24 09 675 15801 1
  • 赛码-接金币-java

    题目描述 小赛非常喜欢玩游戏 最近喜欢上了一个接金币的游戏 在游戏中 使用帽子左右移动接金币 金币接的越多越好 但是金币掉到地上就不能再接了 为了方便问题的描述 我们把电脑屏幕分成11格 帽子每次能左右移动一格 现在给电脑屏幕如图标上坐标
  • 浅谈systemd

    浅谈systemd systemd的基本概念 Systemd的管理服务 Systemd的管理运行级别 systemd的基本概念 一 system的简要介绍 定义 系统启动和服务器守护进程管理器 负责在系统启动或运行时 激活系统资源 服务器进
  • 使用Docker安装Portainer

    打开powershell输入命令 docker run d p 9000 9000 restart always v var run docker sock var run docker sock name prtainer portain
  • 双轮平衡车实现自平衡功能

    1 功能说明 在双轮小车上安装一个六轴陀螺仪传感器 本文示例将实现双轮小车自主平衡功能 2 电子硬件 在这个示例中 我们采用了以下硬件 请大家参考 主控板 Basra主控板 兼容Arduino Uno 扩展板 Bigfish2 1扩展板 传
  • 【Java】Java中的“引用类型”和C中的“指针”区别

    文章目录 前言 1 Java中 基本数据类型 和 引用数据类型 变量在内存分配时的不同 2 C中 指针 的特点 3 Java中 引用 的特点 4 Java的参数传递 5 参考 前言 在学习Java中变量的数据类型时 发现其分为2大类 基本数