Java程序设计语言的细节

preview
需积分: 0 10 下载量 187 浏览量 更新于2008-09-25 收藏 40KB DOC 举报
Java程序设计语言是一门强大的面向对象编程语言,其在软件开发领域广泛应用。本文将探讨一些在实际开发中容易被忽视的Java语言细节,帮助开发者更好地理解和应用Java。 我们来看位移运算的问题。在Java中,位移运算符`<<`用于进行二进制位的左移操作。在处理`a<<b`时,Java会进行优化,将其转化为`a<<(b%32)`。这意味着当左移位数超过32时,实际移动的位数是`b`除以32的余数。因此,对于`int a = 5; System.out.println(a << 33);`这段代码,虽然直觉上可能会认为结果是0,但实际上是10,因为`33 % 32 = 1`,所以`a`只左移了一位。 关于`i != i`的情况。这在数学上看似荒谬,但在Java中是可能的,原因在于浮点数的特殊值NaN(Not a Number)。在IEEE 754浮点数标准中,除以零或其他未定义的浮点计算会产生NaN。例如,`double i = 0.0 / 0.0;`的结果就是NaN。根据规范,NaN不等于任何值,包括它自己,因此`i == i`会返回`false`,导致`System.out.println("No i!=i");`被执行。 接下来讨论的是equals方法的安全覆盖。在Java中,当我们覆盖Object类的equals方法时,需要遵循五个原则:反身性、对称性、传递性、一致性以及非空性。然而,以下代码示例可能存在安全隐患: ```java public class Student { private String name; private int age; // ... 构造函数和成员变量省略 ... public boolean equals(Object obj) { if (obj instanceof Student) { Student s = (Student) obj; if (s.name.equals(this.name) && s.age == this.age) { return true; } } return super.equals(obj); } } ``` 问题在于,`instanceof`运算符允许子类对象被识别为父类实例。如果`Student`有一个子类`CollegeStudent`,那么一个`CollegeStudent`对象和一个`Student`对象在满足相同name和age的情况下,会被错误地判断为相等。为了解决这个问题,我们应该使用`getClass()`方法来精确判断对象类型,确保比较的是相同类型的对象。修正后的代码可以是: ```java public boolean equals(Object obj) { if (obj != null && obj.getClass() == Student.class) { Student s = (Student) obj; if (s.name.equals(this.name) && s.age == this.age) { return true; } } return false; } ``` 理解Java语言中的这些细节对于写出高效、健壮的代码至关重要。位移运算的处理方式、浮点数的特殊值以及equals方法的正确覆盖都是我们在编程时需要注意的关键点。通过深入掌握这些细节,开发者可以避免常见的陷阱,提高代码质量。