当前位置: 首页 > 面试题库 >

Java与常规Java相对应-它们是否等效?

长孙宜
2023-03-14
问题内容

这两个构造是否相等?

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];
    // code goes here
}

也就是说, 如果我在两个循环的主体中放入完全相同的代码(并且它们进行编译),它们的行为将完全相同吗???

完全免责声明:这是受另一个问题启发的(Java:这两个代码是否相同)。我的答案原来不是答案,但是我认为Java for-each的确切语义需要指出一些细微差别。


问题答案:

虽然这两种结构通常可以互换,但它们 并非100%等效

可以通过定义构造证明,// code goes here这将导致两个构造的行为不同。这样的循环体是:

arr = null;

因此,我们现在进行比较:

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

与:

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循环,请 确保保留语义,因为不能保证

尤其要注意对要迭代的数组/集合 的引用 的任何修改( 对内容的
修改可能/可能不会触发ConcurrentModificationException,但这是一个不同的问题)。

当您使用使用自定义迭代器的集合时,确保语义保留也要困难得多,但是如本示例所示,即使涉及简单数组,这两种构造也是不同的。



 类似资料:
  • 问题内容: 我有上述2个类(POJO),它们都是绝对相同的(除了课程名称),我将它们添加到两个数组列表:aListA和aListB。我需要比较两个对象是否相同。如果它们相同,则需要将它们添加到另一个列表(commonList)中,如果它们恰好是不同的,则需要将它们添加到另一个列表(differentList)中。我写了以下代码: 我的问题是,即使两个不同POJO中的数据(变量,firstId和se

  • 问题内容: 我一直在阅读JLS,并且遇到了11.1.3节。我引用的异步异常是: 大多数异常是由于它们所发生的线程的操作而同步发生的,并且在程序中被指定为可能导致此类异常的某个点处发生。相反,异步异常是在程序执行的任何时候都可能发生的异常。 和 异步异常仅由于以下原因而发生: […] * Java虚拟机中的内部错误或资源限制,阻止其实现Java编程语言的语义。在这种情况下,引发的异步异常是Virtu

  • 问题内容: 我需要使用字符串参数并在Python中创建以该字符串命名的类的对象。在Java中,我会使用。在Python中是否有等同功能? 感谢你的答复。回答那些想知道我在做什么的人:我想使用命令行参数作为类名,并实例化它。我实际上是在Jython中编程并实例化Java类,因此是问题的Java实质。 效果很好。非常感谢。 问题答案: python中的反射比Java中的反射更容易,更灵活。 没有直接函

  • 问题内容: 因此,我听说如果将2个字符串与==进行比较,则只有它们都引用相同的对象/实例时,我才会返回true。那是琴弦。布尔呢? 问题答案: ==是否检查布尔值是否完全相等?-Java 这取决于您是在谈论s(对象包装,请注意大写)还是s(原始,请注意小写)。如果您在谈论s(对象包装器),就像处理所有对象一样,请检查 身份 ,而不是对 等 。如果您在谈论s(基元),它将检查是否相等。 所以: 但

  • 问题内容: 我正在上一门计算机科学课程,课程大纲说要下载Java 1.6。我找不到Java 1.6,所有内容都显示JDK6。当我用Java 1.6进行搜索时,发现此链接: http://java.sun.com/javase/downloads/index.jsp 这就是他所说的Java 1.6吗?我下载了JDK 6 update 17和netbeans 6.8。我会给教员发电子邮件并问他这个问题

  • 问题内容: 为什么… 在给定…的情况下导致编译时出现不兼容的类型错误 … 才不是? 为什么我可以比较String和Object的对象引用,而不比较StringBuilder和String的对象引用?它们不是都只是指向存储位置吗? 谢谢 问题答案: 根据Java语言规范(15.21.3): 如果无法通过强制转换将任何一个操作数的类型转换为另一个操作数的类型,则将发生编译时错误(第5.5节)。两个操作