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

在上一篇文章中,我讨论了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中的值类型:为什么它们不可变?相关推荐

  1. Java 基础 —— Java 中的值类型与引用类型

    一.值类型与引用类型 在 Java 中类型可分为两大类:值类型与引用类型.值类型就是基本数据类型(如 int.double 等),而引用类型是指除了基本的变量类型之外的所有类型(如通过 class 定 ...

  2. java引用类型和值类型_[Java教程]JavaScript中值类型和引用类型的区别

    [Java教程]JavaScript中值类型和引用类型的区别 0 2017-02-24 00:00:35 JavaScript的数据类型分为两类:原始类型和对象类型.其中,原始类型包括:数字.字符串和 ...

  3. java不可变类型_Java中的值类型:为什么它们不可变?

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

  4. Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?...

    <Java中,String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?> <Java中的值传递和引用传递> 原理知识: 如果参数类型是原始类型,那么传过来的就是这 ...

  5. 为什么说 Java 中只有值传递?

    对于初学者来说,要想把这个问题回答正确,是比较难的.在第二天整理答案的时候,我发现我竟然无法通过简单的语言把这个事情描述的很容易理解,遗憾的是,我也没有在网上找到哪篇文章可以把这个事情讲解的通俗易懂. ...

  6. Java中,一切皆是对象——java中的对象类型与基本数据类型的区别

    起因:取一个list给另一个list赋值,然后在另一个list中取出进行修改.list其中类型为对象时,String时,基本数据类型时. [java中的对象类型与基本数据类型的区别] #声明和实例化 ...

  7. java中的null类型---有关null的9件事

    摘自 https://blog.csdn.net/qq_25077777/article/details/80174763 今天听到一个问题,java中的null类型,null竟然是一种类型 java ...

  8. .NET中的值类型与引用类型

    .NET中的值类型与引用类型 这是一个常见面试题,值类型(Value Type)和引用类型(Reference Type)有什么区别?他们性能方面有什么区别? TL;DR(先看结论) 值类型 引用类型 ...

  9. byte java byte_详解java中的byte类型

    Java中整数类型有:byte占8位, short 占16位, int占32位, long占64位 Java也提供了一个byte数据类型,并且是基本类型中的整数类型.java byte是作为最小的数字 ...

最新文章

  1. 计算机专业数控,数控专业的月薪是多少 数控专业能干什么
  2. PyQt5 技术篇-在clipboard.dataChanged.connect()里如何写入剪切板示例演示,pyqt5监听剪切板变动并写入剪切板内容
  3. CSS3-实现单选框radio的小动画
  4. 真香!原来 CLI 开发可以这么简单
  5. SpringBoot 2.x 监控中心:Admin
  6. 认识与设计Serverless(二)
  7. nyoj 55 懒省事的小明 优先队列 multiset 还有暴力
  8. 2014-01-01
  9. 米家电磁炉显示e10_米家电磁炉e10故障怎么回事
  10. 对于局部变量,text、ntext 和 image 数据类型无效
  11. 【回波损耗(dB)和电压驻波比(VSWR)之间的关系】
  12. Unhandled rejection Error: EACCES: permission denied, open '/Users
  13. 图像压缩编码和解码原理——阐述了DCT变换的实质
  14. coap python_Python coap
  15. 利用python爬取东方财富网股吧评论并进行情感分析(一)
  16. 有趣的十个Python实战项目,让你瞬间爱上Python!
  17. input标签type为number时如何去除加减按钮效果
  18. ubuntu14.04 64位安装H3C iNode客户端
  19. 80C51单片机复习资料(一)
  20. 并发模拟的四种方式+工具,超级实用!

热门文章

  1. 输入框限定保留三位小数点
  2. say小组KTV点歌系统简介
  3. java中,如何实现输入一个正整数,并将这个数字反转输出,比如输入123,输出321
  4. 搭建ssh框架的步骤
  5. java循环结构教程
  6. javaWeb服务详解(含源代码,测试通过,注释) ——applicationContext-dao.xml
  7. Tomcat9.0 设置局域网内其他电脑或手机端访问{9.0更新}
  8. mysql - Docker Wordpress连接到本地主机上的数据库服务器
  9. python处理脑电信号_用ICA去除脑电信号中的眼球链接
  10. aws上负载均衡器标组端口_AWS CloudFormation:目标组没有关联的负载均衡器