java不可变类型

值类型不必是不变的。 但是他们是。

在上一篇文章中,我讨论了Java中指针与引用之间的区别以及如何传递方法参数(按值传递或按引用传递)。 这些与Java中尚不存在的值类型密切相关(尚未)。

John Rose,Brian Goetz和Guy Steele 提出了一个建议 ,详细介绍了值类型将如何/可能在Java中工作,并且还有一些很好的文章。 我已经阅读了我非常喜欢的“值类型:改造Java的类型系统” ,我建议阅读。 如果建议过于密集,以至于您无法关注该主题,则可以先阅读该文章。 它非常概括了背景,值类型是什么,优点,为什么Java不实现值类型是一个问题以及为什么它不是琐碎的问题。 即使术语“值类型”也可以用来表示不同的东西,我也会在提案和文章中使用它。

我们如何传递参数与我们在变量中存储什么

您可能还记得上一篇文章,我详细介绍了Java根据参数的类型按引用或按值传递方法参数:

  • 当参数是对象时传递引用
  • 参数为原始值时按值排序。

在原始帖子上以及在JCG重新发布 上都有一些评论,这些评论抱怨我关于通过引用传递论点的术语。 注释指出,参数总是按值传递,因为变量已包含对对象的引用。 实际上,变量包含位。 即使了解我们如何想象这些位以及在交流时使用什么术语,这一点很重要。 我们可以说

  1. 类变量包含对象,在这种情况下,我们通过引用将这些对象传递给方法
  2. 或者我们可以说变量包含引用,在这种情况下,我们传递变量的值。

如果我们遵循思想#1,则根据参数(对象或基元)的实际性质,参数传递是按值和/或按引用。 如果我们遵循思想#2,则变量将根据其类型的性质存储参考和/或值。 我个人想写的时候

Triangle triangle;

则可变triangle是三角形,而不是对三角形的引用。 但这与我的大脑到底有什么关系并不重要。 在情况#1或#2中,对于类类型和基元都有不同的方法。 如果我们在语言中引入值类型,则区别将变得更加普遍和易于理解。

值类型是不可变的

我解释说,基于类型的隐式参数传递不会引起任何问题,因为基元是不可变的,因此,当作为方法参数传递时,即使通过引用传递它们也无法更改。 所以我们通常不在乎。 值类型没有不同。 值类型也是不可变的,因为它们是值,并且值不变。 例如,PI的值为3.145926…,并且它永远不会改变。

但是,这种不变性在编程中意味着什么? 值可以是实数,整数或复合值类型,它们在内存中均以位表示。 可以更改内存中的位(除非内存是ROM)。

在对象不变的情况下,相当简单。 宇宙中某个地方有一个我们无法改变的物体。 可能有许多保存对象的变量(对其有一个引用),并且代码可以依赖于这样的事实,即表示对象实际值的存储位置中的位不变(或多或少)。

在值类型的情况下,这有点不同,并且这种差异是由于相同位在表示对象时对表示值类型的位的解释不同。

值类型没有身份

值类型没有身份。 您不能有两个保存值3 int变量并区分另一个。 它们具有相同的价值。 当类型更复杂时,也是如此。

假设我有一个具有两个字段的值类型,例如

ValueType TwoFields {int count;double size;}

说我有两个变量

Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = new TwoFields(1,3.14)

我不能告诉其他变量tF1tF2 。 如果他们的对象,他们是equals彼此但不==对方。 对于值类型,没有==因为它们没有身份。

如果TwoFields是不可变的类,我不能或不应该写

TwoFields tF;...tF.count++;

或一些类似的结构。 但我仍然可以写

TwoFields tF;...tF = new TwoFields(tF.count+1, tF.size)

保持原始对象不变。 如果TwoFields是值类型,则无论哪种构造,都将创建一个新值。

值类型作为参数

值类型如何作为方法参数传递呢? 可能将值复制到参数变量。 可能会传递一些参考。 但是,这取决于编译器(是Java还是其他语言)。 为什么?

  • 值类型通常很小。 至少它们应该很小。 巨大的值类型失去了值类型提供的优点,但有缺点。
  • 值类型是不可变的,因此像原始类型一样复制它们没有问题。 可以按值传递它们的方式与“ Java的所有内容都按值传递”的方式相同。
  • 它们没有身份,不能引用它们。

但这不仅是将它们作为参数传递。 这也是分配变量的方式。 看代码

Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = new TwoFields(1,3.14)

比较一下

Twofields tF1 = new TwoFields(1,3.14)Twofields tF2 = tF1

如果TwoFields是值类型,则两个版本之间应该没有区别。 它们必须产生相同的结果(尽管在编译时可能不会通过相同的代码)。 在这方面,参数传递和变量赋值之间没有真正的区别。 即使实际变量作为位包含对存储值的某些存储位置的某些引用,也会复制值。

摘要

在我开始撰写本文时:值类型不必是不变的。 这不是语言设计师决定的事情。 他们可以自由地实现可变的东西,但是在那种情况下,它将不是值类型。 值类型是不可变的。

翻译自: https://www.javacodegeeks.com/2016/01/value-types-java-immutable.html

java不可变类型

java不可变类型_Java中的值类型:为什么它们不可变?相关推荐

  1. java中的string类型_Java中的字符串类型(String)

    String 字符串是一个引用数据类型,字符串都是对象. String特性:1.在程序中出现的字符串字面量(常量),在程序中运行时会以对象的形式保存在JVM内存的字符串池中,并且所有的这些字符串字面量 ...

  2. Java+包裹类型_java中的包裹类型

    包裹类型将一个基本数据类型的数据转换成对象的形式,从而使得它们可以像对象一样参与运算和传递.下表列出了基本数据类型所对应的包裹类型: 基本类型    包裹类型 boolean    Boolean c ...

  3. java 7种枚举类型_Java中的枚举类型

    枚举类比较用 == 还是 equals,有啥区别? java 枚举值比较用 == 和 equals 方法没啥区别,两个随便用都是一样的效果.因为枚举 Enum 类的 equals 方法默认实现就是通过 ...

  4. java记录类型_Java中的记录类型

    java记录类型 于2020年3月发布的JDK 14引入了记录 (预览语言功能),该记录提供了一种紧凑的语法来声明主要用于保存数据的类. 在记录中 ,所有低级,重复且容易出错的代码都类似于构造函数,访 ...

  5. java map 允许重复_java中key值可以重复的map:IdentityHashMap

    在Java中,有一种key值可以重复的map,就是IdentityHashMap.在IdentityHashMap中,判断两个键值k1和 k2相等的条件是 k1 == k2 .在正常的Map 实现(如 ...

  6. java 设计char类型_JAVA中的char类型

    1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a';  //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=1 ...

  7. java的幂运算_java中幂指数值的运算

    说到幂指数的运算我们就会用到Math.pow(double a,double b),返回的结果是a的b次方. 这个方法可以满足我们大多数幂指数的计算,但是每次访问的值和传入的值都是double,自己不 ...

  8. java中double类型_Java中的Double类型计算

    1 package com.wetalk.wbs.bas.util; 2 3 import java.io.Serializable; 4 import java.math.BigDecimal; 5 ...

  9. Java中的值类型:为什么它们不可变?

    值类型不必是不变的. 但是他们是. 在上一篇文章中,我讨论了Java中指针与引用之间的区别以及如何传递方法参数(按值传递或按引用传递). 这些与Java中尚不存在的值类型密切相关(尚未). John ...

最新文章

  1. RabbitMQ 6种工作模式
  2. CTFshow php特性 web144
  3. 用J-Link烧写u-boot到Nor Flash—— 韦东山嵌入式Linux视频学习笔记04
  4. 记录一下Struts2升级遇到的问题
  5. apache ignite_Kubernetes集群上的Apache Ignite和Spring第2部分:Kubernetes部署
  6. STM32基于AD5663的UV灯电压控制
  7. MongoDB的查询语法和SQL的SELECT语法做对比
  8. vue父子组件生命周期执行顺序_关于Vue组件的生命周期及执行顺序
  9. LINUX 第六章 Open WebMail完全安装手册
  10. lisp中getkword输入默认_2分钟学会在Word中制作田字格 米字格 书法练字再也不用买本子了...
  11. 17082 两个有序数序列中找第k小
  12. 简单的实现HTTP密码验证登陆
  13. 批量修改WORD文档密码
  14. brew 特别慢 解决方案
  15. GROMOS拓扑(、坐标、轨迹、能量)相关文件解读手册第5章阅读笔记II
  16. Peekaboo—站立式会议+alpha冲刺:Day2冲刺随笔
  17. 按键精灵post请求_按键精灵安卓版能发送post和get请求吗
  18. mongodb基本命令及操作
  19. c语言字母菱形金字塔编程,C语言打印菱形、金字塔
  20. linux建立u盘引导分区表,创建Linux之USB启动盘

热门文章

  1. P4196-[CQOI2006]凸多边形/[模板]半平面交【计算几何】
  2. jzoj3379-查询【主席树】
  3. POJ2482-Stars in Your Window【线段树,扫描线,离散化】
  4. P1892-团伙【图论,并查集】
  5. 2020 ICPC亚洲区域赛(沈阳)F-Kobolds and Catacombs(思维+模拟)
  6. ACL Beginner Contest 总结——F多项式待补
  7. 【dfs】家族(jzoj 1985)
  8. 洛谷 动态规划一日游 P2577、P1070、P2051
  9. 操作系统复习笔记 04 Process 进程
  10. 零配置 之 Spring 注解实现Bean依赖注入