Java程序员应该了解哪些常见的未定义行为 3 周,1 日 Questions & Answers 7149 与this问题相同,但适用于java 更新 根据一些人的评论和回应,很明显Java几乎没有未定义的行为 所以我也想问一下什么行为不明显回答时请区分两者:)
# 1 楼答案 Serialization。它本身并不是未定义的(有一个确定性算法)。但是,对于一般的观察者来说,什么会或不会导致serialVersionUID的更改并不明显,从而挫败了您使用RMI、JMS和各种其他首字母缩略词的所有尝试 因此,当您知道需要序列化对象时,通常最好使用consider your options。我特别喜欢“始终将it作为一个领域”的技巧: private static final long serialVersionUID = 1L; 只有当开发人员知道您的代码发生了更改时,才更改该字段的值。不要让JDK替你做决定
# 2 楼答案 与线程有关的任何内容…:) 此外: 重写方法,并期望它们在版本之间以相同的方式使用 关于底层平台的假设(例如,文件分隔符) 垃圾收集/最终确定的详细信息 关于类初始化的一些细节 是否为整数。valueOf(等)返回相同的对象 性能、延迟和内存使用
# 3 楼答案 我不完全确定您所说的“未定义的行为”是什么意思,但正如其他人所指出的,核心语言在不同平台、不同版本的语言和JVM之间都是非常可预测的 然而,对于图形(Swing、AWT),情况并非如此,因为图形往往不可预测,并且不一定能够在不同的平台上重现。我在一个基于Java的图形密集型可视化应用程序上工作,我花了很多时间“编写一次,到处调试” 还有,反对。clone()有一些主要问题,在大多数情况下不鼓励使用它。请参阅Joshua Bloch的“有效Java”中的第11项,以获得完整的答案
# 5 楼答案 Java中几乎没有未定义的行为,与C/C++相比,它是一个定义更明确的平台。原因是C/C++编译器旨在为非常不同的平台生成代码,因此被授予了相当广泛的自由,以防止过于严格的要求迫使编译器为给定平台生成次优代码 Java以非常精确的方式定义了几乎所有的行为,并且只允许很小的自由度,从而牺牲了其中的一部分。这当然使平台更易于处理 未定义行为发生的主要领域是多线程的精确计时和调度(正如Tom Hawtin已经提到的) 不过,有几个地方的行为并不明显,因此可能看起来没有定义,但事实并非如此(Oscar Reyes给出的字符串比较示例就是一个很好的例子) 在一些地方,行为被定义为未定义(例如,HashMap中元素的顺序被定义为依赖于实现,不需要是常量)
# 6 楼答案 定义明确但不明显: 平等性的对象测试: ==用于测试引用(这两个对象引用是否指向同一个对象) 而equals用于测试对象的相等性 比如说 new String("test") == new String("test") 是假的,而 new String("test").equals( new String("test") ) 是真的 字符串对象被插入,因此以下返回true: String a = "test"; String b = "test"; a == b // returns true 但是如果字符串是在其他地方创建的(例如,从数据库创建) String a = "test"; String b = getFromDataBase(); // internally the remote returns "test" a == b // returns false. 验证是错误的 我在jsp中看到了scriplets,新程序员不明白为什么要验证 <%if( param == "continue" ) { %> 永远不会发生
# 1 楼答案
Serialization。它本身并不是未定义的(有一个确定性算法)。但是,对于一般的观察者来说,什么会或不会导致serialVersionUID的更改并不明显,从而挫败了您使用RMI、JMS和各种其他首字母缩略词的所有尝试
因此,当您知道需要序列化对象时,通常最好使用consider your options。我特别喜欢“始终将it作为一个领域”的技巧:
只有当开发人员知道您的代码发生了更改时,才更改该字段的值。不要让JDK替你做决定
# 2 楼答案
与线程有关的任何内容…:)
此外:
# 3 楼答案
我不完全确定您所说的“未定义的行为”是什么意思,但正如其他人所指出的,核心语言在不同平台、不同版本的语言和JVM之间都是非常可预测的
然而,对于图形(Swing、AWT),情况并非如此,因为图形往往不可预测,并且不一定能够在不同的平台上重现。我在一个基于Java的图形密集型可视化应用程序上工作,我花了很多时间“编写一次,到处调试”
还有,反对。clone()有一些主要问题,在大多数情况下不鼓励使用它。请参阅Joshua Bloch的“有效Java”中的第11项,以获得完整的答案
# 4 楼答案
我认为Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases这本书将非常有用,它解释了java的许多隐藏点和未定义的行为
# 5 楼答案
Java中几乎没有未定义的行为,与C/C++相比,它是一个定义更明确的平台。原因是C/C++编译器旨在为非常不同的平台生成代码,因此被授予了相当广泛的自由,以防止过于严格的要求迫使编译器为给定平台生成次优代码
Java以非常精确的方式定义了几乎所有的行为,并且只允许很小的自由度,从而牺牲了其中的一部分。这当然使平台更易于处理
未定义行为发生的主要领域是多线程的精确计时和调度(正如Tom Hawtin已经提到的)
不过,有几个地方的行为并不明显,因此可能看起来没有定义,但事实并非如此(Oscar Reyes给出的字符串比较示例就是一个很好的例子)
在一些地方,行为被定义为未定义(例如,HashMap中元素的顺序被定义为依赖于实现,不需要是常量)
# 6 楼答案
定义明确但不明显:
平等性的对象测试:
==用于测试引用(这两个对象引用是否指向同一个对象)
而equals用于测试对象的相等性
比如说
是假的,而
是真的
字符串对象被插入,因此以下返回true:
但是如果字符串是在其他地方创建的(例如,从数据库创建)
验证是错误的
我在jsp中看到了scriplets,新程序员不明白为什么要验证
永远不会发生