Java 反直觉代码

标签 java

我记得读过一本书,名叫:

Java Puzzlers Traps, Pitfalls, and Corner Cases

描述了 Java 代码中的奇怪行为。看起来完全无辜但实际上与显而易见的东西完全不同的东西。一个例子是:

(编辑:这篇文章不是对这个特定示例的讨论。这是我提到的书中的第一个示例。我问的是您可能遇到的其他奇怪问题。)

这个代码可以用来识别一个数字是否是奇数吗?

public static boolean isOdd(int i) {

    return i % 2 == 1;

}

答案当然是否定的。如果将负数插入其中,则当数字为奇数时会得到错误的答案。正确答案是:

public static boolean isOdd(int i) {

    return i % 2 != 0;

}

现在我的问题是您遇到的最奇怪、最反直觉的 Java 代码是什么?(我知道这不是一个真正的问题,也许我应该将其发布为社区 wiki,拜托建议)

最佳答案

一个我blogged about最近,给定以下两个类:

public class Base
{
   Base() {
       preProcess();
   }

   void preProcess() {}
}


public class Derived extends Base
{
   public String whenAmISet = "set when declared";

   @Override void preProcess()
   {
       whenAmISet = "set in preProcess()";
   }
}

当一个新的 Derived 对象被创建时,你认为 whenAmISet 的值是多少?

给定以下简单的主类:

public class Main
{
   public static void main(String[] args)
   {
       Derived d = new Derived();
       System.out.println( d.whenAmISet );
   }
}

大多数人说输出看起来应该是“在 preProcess() 中设置”,因为 Base 构造函数调用了该方法,但事实并非如此。 Derived 类成员在 调用 Base 构造函数中的 preProcess() 方法后初始化,该构造函数覆盖preProcess()中设置的值。

Creation of New Class Instances JLS 的部分对创建对象时发生的一系列事件进行了非常详细的解释。

关于Java 反直觉代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1147245/

相关文章:

JavaCC:如何指定在特定上下文中需要哪些 token ?

java - 如何使用 ParameterNameAware

java - 在子类中设置父类(super class)字段

java - 静态方法和实例方法之间的区别

java - 使用 hibernate 和 seam 保持多对多关系

java - @Cacheable 与内存数据库?

java - 处理异常后如何恢复代码运行?

java - 我正在尝试使用 JAVA 从字符串中获取 URL

Java错误的用户名或密码消息似乎无法工作

java - 我需要一个正则表达式模式,它匹配数字后跟点最多 5 次,不带空格