Ch02-Java 之 Q/A
January 2, 2017
1. a==b
和a.equals(b)
有什么区别?
#
如果 a 和 b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b 指向的是堆中的同一个对象才会返回 true,而 a.equals(b) 是进行逻辑比较,所以通常需要重写该方法来提供逻辑一致性的比较。例如,String 类重写 equals() 方法,所以可以用于两个不同对象,但是包含的字母相同的比较。
2. a.hashCode()
有什么用?与 a.equals(b)
有什么关系?
#
hashCode()
方法是相应对象整型的 hash 值,根据 Java 规范,两个使用 equals()
方法来判断相等的对象,其 hash code 必须相等。
3. final
、finalize
和 finally
的不同之处?
#
条目 | 说明 |
---|---|
final | 是一个修饰符,可以修饰变量、方法和类。如果 final 修饰变量,意味着该变量的值在初始化后不能被改变。 |
finalize | 允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。 |
finally | 是一个关键字,与 try 和 catch 一起用于异常的处理。finally 块一定会被执行,无论在 try 块中是否有发生异常。 |
4. String、StringBuffer 与 StringBuilder 的区别 #
- 可变和适用范围。String 对象是不可变的,而 StringBuffer 和 StringBuilder 是可变字符序列。每次对 String 的操作相当于生成一个新的 String 对象,而对 StringBuffer 和 StringBuilder 的操作是对对象本身的操作,而不会生成新的对象,所以对于频繁改变内容的字符串避免使用 String,因为频繁的生成对象将会对系统性能产生影响。
- 线程安全。String 由于有 final 修饰,是 immutable 的,安全性是简单而纯粹的。StringBuilder 和 StringBuffer 的区别在于 StringBuilder 不保证同步,也就是说如果需要线程安全需要使用 StringBuffer,不需要同步的 StringBuilder 效率更高。
5. 移位运算符 #
运算符 | 说明 |
---|---|
<< |
左移运算符,x << 1 ,相当于 x 乘以 2 (不溢出的情况下),低位补 0 |
>> |
带符号右移,x >> 1 ,相当于 x 除以 2,正数高位补 0,负数高位补 1 |
>>> |
无符号右移,忽略符号位,空位都以 0 补齐 |
6. 如何理解 Java 中的泛型是伪泛型?泛型中类型擦除? #
Java 泛型这个特性是从 JDK 1.5 才开始加入的,因此为了兼容之前的版本,Java 泛型的实现采取了“伪泛型”的策略,即 Java 在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样。
- 消除类型参数声明,即删除<>及其包围的部分。
- 根据类型参数的上下界推断并替换所有的类型参数为原生态类型:如果类型参数是无限制通配符或没有上下界限定则替换为 Object,如果存在上下界限定则根据子类替换原则取类型参数的最左边限定类型(即父类)。
- 为了保证类型安全,必要时插入强制类型转换代码。
- 自动产生“桥接方法”以保证擦除类型后的代码仍然具有泛型的“多态性”。