。(點擊上方公眾號,可快速關注)
編譯:ImportNew - 心靈是一棵開花的樹,
如有好文章投稿,請點擊 → 這裏了解詳情
作為Java 控,我們總是對不太可能直接使用,但能使我們更了解 Java 和 Java 虛擬機(Java Virtual Machine,JVM) 的晦澀細節感興趣。這也是我將 Lukas Eder 在 jooq.org 上寫的這篇文章發布出來的原因。
你在Java發布的時候就開始使用了嗎?還記得那時它叫"Oak",麵向對象也 (Object Oriented, OO )還是個熱門話題,C++ 程序員們覺得 Java 完全沒機會成功,Applet的出現也是一件新鮮大事?
我打賭下文中至少一半的內容你都不知道。讓我們來看看這些令人驚喜的 Java 細節吧。
1. 受檢異常(checked exception)這件事是不存在的
是這樣的,JVM 完全不知道這件事,都是Java語言做的[隻有Java語言這麼幹]。
現在,異常檢查被公認為是個錯誤,正如 Brue Eckel 在布拉格的 GeeCON 大會上的閉幕詞中所說, Java 後的其他語言都不再使用異常檢查了,就連 Java 8 都不願在新的 Stream API 中使用它了(當你在 lambda 表達式中使用 IO 或者 JDBC 時,是很痛苦的)。
你想要證明 JVM 不知道異常檢查這件事嗎?嚐試以下代碼:
public class Test {
// No throws clause here
public static void main(String[] args) {
doThrow(new SQLException());
}
static void doThrow(Exception e) {
Test.
doThrow0(e); }
@SuppressWarnings("unchecked")
static
void doThrow0(Exception e) throws E { throw (E) e;
}
}
這個不僅會編譯,還會拋出 SQLException ,你甚至不需要 Lombok 的 @SneakyThrows 標簽。
更多詳情請參考這篇文章,
https://blog.jooq.org/2012/09/14/throw-checked-exceptions-like-runtime-exceptions-in-java/
或者 Stack Overflow 上的這篇文章。
http://stackoverflow.com/q/12580598/521799
2. 可以使用不同的返回值類型來重載方法
以下代碼是編譯不過的,對吧?
class Test {
Object x() { return "abc"; }
String x() { return "123"; }
}
是的,Java 不允許在一個類中通過不同的返回值類型和異常語句來重載方法。
不過稍等,Java 文檔中關於 Class.getMethod(String, Class…) 這樣寫道:
請注意,在一個類中會有多個匹配的方法,因為雖然 Java 語法規則禁止一個類中存在多個方法函數簽名相同僅僅返回類型不同,但 JVM 允許。這樣提高了 JVM 的靈活性以實現各種語言特性。例如,可以用橋接方法(bridge method)來實現方法的協變返回類型,橋接方法和被重載的方法可以有相同的函數簽名和不同的返回值類型。
喔,這是合理的。事實上,以下代碼就是這樣執行的,
abstract class Parent {
abstract T x();
}
class Child extends Parent {
[email protected]
String x() { return "abc";}
}
Child 類編譯後的字節碼是這樣的:
相關文章// Method descriptor #15 ()Ljava/lang/String;
// Stack: 1, Locals: 1
java.lang.String x();
0 ldc
没有评论:
发表评论