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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mac设置首页访问php,mac系统下php项目除了首页全访问不了

有网友反映mac配置apache的有问题,除了首页全都访问不了,小编找来了相关的解决办法,有需要的朋友可以来了解一下。httpd.conf配置文件中加载了mod_rewrite.so模块AllowOverride None 将None改为 AllDocumentRoot "/Library/WebServer/Do…

java filter 模式,Java设计模式----过滤器模式(挑三拣四)

过滤器模式描述拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,然后把请求传给相…

表单

表单本身也是DOM树 表单的输入框、下拉框等可以接收用户输入&#xff0c;所以用JavaScript来操作表单&#xff0c;可以获得用户输入的内容&#xff0c;或者对一个输入框设置新的内容。 HTML表单的输入控件主要有以下几种&#xff1a; 文本框&#xff0c;对应的<input type&q…

java项目processes设置,Jvm调优和SpringBoot项目优化的详细教程

参考文章1、先看一下未设置JVM参数的情况&#xff0c;默认情况下&#xff0c;没有设置任何Jvm参数。2、设置Jvm参数。配置参数&#xff1a;关于这些设置的JVM参数是什么意思&#xff0c;参考Jvm调优。-XX:MetaspaceSize128m (元空间默认大小)-XX:MaxMetaspaceSize128m (元空间最…

Git问题Everything up-to-date解决

Git问题Everything up-to-date解决 【自己的亲身错误体验】 我的上一篇博客&#xff0c;说了怎么上传一个项目到git远程上面。今天我写好一个小栗子&#xff0c;准备再次上传的时候。我依旧是放在我的F:\github\js- 这个和我的github上的远程仓库相同名称的文件中的 在这里空白…

java超出gc开销限制_超出了GC开销限制– Java堆分析

java超出gc开销限制这篇文章是我们原来的GC开销超出问题模式的延续。 正确的Java堆分析对于消除O​​utOfMemoryError&#xff1a;GC开销问题至关重要。 如果您不熟悉此Java HotSpot 1.6错误&#xff0c;建议您首先阅读有关此主题的第一篇文章 。 本文将为您提供一个示例程序和…

Java接口long类型精度丢失,解决前后端交互Long类型精度丢失问题

雪花算法ID&#xff0c;对应的后端Long类型&#xff0c;前端number类型&#xff0c;它们的精度不一样&#xff0c;导致精度丢失现象雪花算法得到的ID较长&#xff0c;传到前端后&#xff0c;精度丢失库中&#xff1a;23754851322302474后端&#xff1a;23754851322302474前端&a…

如何模拟Spring bean(版本2)

大约一年前&#xff0c;我写了一篇博客文章如何模拟Spring Bean 。 所描述的模式对生产代码几乎没有侵入性。 正如读者Colin在评论中正确指出的那样&#xff0c;基于Profile注释的间谍/模拟Spring bean是更好的选择。 这篇博客文章将描述这种技术。 我在工作中以及副项目中都成…

eclipse和jdk的版本问题,比如printf()出错

1.右键项目选中properties 2.Java Builder Path 》》》Libraries》》》选中JRE Syste Library[jre7]然后remove 3.Add Library》》》JRE Syetem Library》》》NEXT》》》Alternate JRE:选中最新的jie版本 4.Finish》》》OK&#xff01; 5.再在右键项目选中properties 》》》Ja…

java自定义一个timeout,Timeout操作符 RxJava 学习笔记二十一

timeout用于检测在给定时间内observables没有及时响应。如果指定的时间量没有发出任何项目&#xff0c;则超时会使observables失败并出现TimeoutException。我们将从debounce的示例中重用我们的observable来演示超时。输出&#xff1a;只要值不超过200ms&#xff0c;就会输出。…

用xshell ssh连接测试服务器时候出的问题

问题还原&#xff1a;用ssh连接测试服务器 给我结结实实报了个错 FBIwarning: ----------------------------------------------------------------------------------------------------------------------------以上 问题还原 解决过程&#xff1a;百度 博客地址http://blog.…

maven集成spring_Maven集成测试和Spring Restful Services

maven集成spring介绍 我的原始博客通过一个非常简单的示例展示了如何分离Maven单元和集成测试。 http://johndobie.blogspot.com/2011/06/seperating-maven-unit-integration-tests.html此后&#xff0c;许多人要求我提供比最初使用的示例更实际的示例。 这篇文章显示了如何在实…

WebService.asmx架设后,显示调用按钮的方法

我们在VS本地调试WebService的时候&#xff0c;页面是可以调试的&#xff0c;如下图 但是在发布以后&#xff0c;通过浏览器访问服务器上的地址&#xff0c;是不能调试你的程序的&#xff0c;就变成了这个样子&#xff1a; 可以通过修改服务器上的web.config达到远程调试的效果…

复习者-Java EE 7概览

随着红帽JBoss企业应用平台7&#xff08;EAP 7&#xff09;的出现&#xff0c;甚至最近刚刚通过Java EE 7认证的WebLogic服务器&#xff0c;我认为现在应该为您重新介绍Java Enterprise Edition 7的时候了功能&#xff0c;并指向更多资源。 Java EE 7 –开发人员的生产力&…

php教程知识点归纳,PHP知识点小结

PHP知识点总结?1.?DIRECTORY_SEPARATOR??? ? ? 因为在window上分隔符是"\"而在linux上分隔符是"/" ?使用这个符号就可以避免这个问题。??2.?realpath??? ? ?返回文件所在的绝对路径。??3. 在php中 0null 是成立的。?? ???4.file_ge…

40:数组中只出现一次的数字

/*** 面试题40&#xff1a;数组中只出现一次的数字* 一个整型数组里除了两个数字之外&#xff0c;其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。*/ public class _40_num_one_times {public static void main(String[] args){Solution40 solution40 new Solu…

按窗口文件php代码,在Windows命令行窗口中输入并运行PHP代码片段(不需要php文件)的方法...

有时候只是简单的为了测试某个php函数的效果&#xff0c;以前总是需要建一个php文件&#xff0c;复制这个文件的路径&#xff0c;再通过web访问或者用php命令执行这个php文件。一直想要怎么才能不用创建文件&#xff0c;才能直接执行PHP代码片段呢&#xff1f;终于找到了方法&a…

MySQL 汉字转拼音

一 . fristPinyin &#xff1a; 此函数是将一个中文字符串的第一个汉字转成拼音字母 &#xff08;例如&#xff1a;"中国人"->Z&#xff09; CREATE FUNCTION fristPinyin(P_NAME VARCHAR(255)) RETURNS varchar(255) CHARSET utf8 BEGINDECLARE V_RETURN VARCHAR…

java中npe问题,【Java 8】巧用Optional之优雅规避NPE问题

避之不及的 NullPointerExceptionNPE : NullPointerException空指针异常是最常见的Java异常之一&#xff0c;抛出NPE错误不是用户操作的错误&#xff0c;而是开发人员的错误&#xff0c;应该被避免&#xff0c;那么只能在每个方法中加入非空检查&#xff0c;阅读性和维护性都比…

adf435编程_动态ADF列车:以编程方式添加列车停靠点

adf435编程我将展示如何以编程方式“即时”将火车停靠站添加到ADF火车中。 在我的用例中&#xff0c;我有一些票务预订应用程序。 它具有训练模型的有限任务流。 在火车的第一站&#xff0c;用户输入乘客数量&#xff0c;在随后的站点&#xff0c;他们输入一些乘客信息。 必须根…