每个Java与常规的Java是否相同?

编程入门 行业动态 更新时间:2024-10-27 21:19:09
本文介绍了每个Java与常规的Java是否相同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

char [] arr = new char [5]; for(char x:arr){ // code goes here }

比较:

char [] arr = new char [5]; for(int i = 0; i< arr.length; i ++){ char x = arr [i]; //代码在这里}

即 if我把两个循环(和他们编译)的主体完全相同的代码,他们会表现完全一样吗?

完整免责声明:这受到另一个问题的启发( Java :这两个代码是相同的吗?我的答案原来不是答案,但我觉得Java的确切语义 - 每个都有一些需要指出的细微差别。

解决方案

虽然这两个结构通常是可以互换的,但它们并不是100%等同的!

通过定义 //代码在这里这会导致这两个结构行为不同。一个这样的循环体是:

arr = null;

因此,我们现在比较:

char [] arr = new char [5]; for(char x:arr){ arr = null; $ / code $ / pre

char [] arr = new char [5]; for(int i = 0; i< arr.length; i ++){ char x = arr [i]; arr = null; }

这两个代码编译,但是如果你运行它们,你会发现第一个循环终止正常,而第二个循环将抛出 NullPointerException 。

这意味着它们不是相当于100%!在这种情况下,两种结构的表现会有所不同!

这种情况可能很少见,但调试时不应该忘记这一点,否则你可能会错过一些非常微妙的错误。

作为一个附录,注意有时for-each结构甚至不是选项,例如如果你需要索引。这里至关重要的一点是,即使它是一个选项,你也需要确保它是一个等价的替代品,因为它并不总是能保证的

类似地,如果你从一个for-each循环开始,并且后来意识到你需要切换到索引for循环,那么确保你保留了语义,因为它不能保证。 p>

特别的,_be对于正在被迭代的数组/集合的引用进行任何修改都很谨慎(修改为内容可能/不会触发 ConcurrentModificationException ,但是这是一个不同的问题)。

保证语义保存也是更多当使用使用自定义迭代器的集合时很困难,但正如这个例子所示,即使涉及简单的数组,这两个构造也是不同的。

Are these two constructs equivalent?

char[] arr = new char[5]; for (char x : arr) { // code goes here }

Compared to:

char[] arr = new char[5]; for (int i = 0; i < arr.length; i++) { char x = arr[i]; // code goes here }

That is, if I put exactly the same code in the body of both loops (and they compile), will they behave exactly the same???

Full disclaimer: this was inspired by another question (Java: are these 2 codes the same). My answer there turned out not to be the answer, but I feel that the exact semantics of Java for-each has some nuances that needs pointing out.

解决方案

While often the two constructs are interchangeable, THEY ARE NOT 100% EQUIVALENT!!!

A proof can be constructed by defining // code goes here that would cause the two constructs to behave differently. One such loop body is:

arr = null;

Therefore, we are now comparing:

char[] arr = new char[5]; for (char x : arr) { arr = null; }

with:

char[] arr = new char[5]; for (int i = 0; i < arr.length; i++) { char x = arr[i]; arr = null; }

Both code compiles, but if you run them, you will find that the first loop terminates normally, while the second loop will throw a NullPointerException.

This means that they are not 100% equivalent! There are scenarios where the two constructs will behave differently!

Such scenarios are likely to be rare, but this fact should not be forgotten when debugging, because otherwise you might miss some really subtle bugs.

As an addendum, note that sometimes the for-each construct is not even an option, e.g. if you need the index. The crucial lesson here is that even if it's an option, you need to make sure that it's actually an equivalent substitute, because it's not always guaranteed

Similarly, if you start with a for-each loop and later realized that you need to switch to the indexed for loop, make sure that you're preserving the semantics, because it's not guaranteed.

In particular, _be wary of any modification to the reference of the array/collection being iterated_ (modification to the content may/may not trigger ConcurrentModificationException, but that's a different issue).

Guaranteeing semantics preservation is also a lot more difficult when you use collections that use custom iterators, but as this example shows, the two constructs are different even when simple arrays are involved.

更多推荐

每个Java与常规的Java是否相同?

本文发布于:2023-11-12 07:04:08,感谢您对本站的认可!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:常规   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!