Java不为人知的10个真相
你是不是一开始就用
Java来编程的呢?还记得当年它还被称为"Oak",OO还是热门的话题,C++的用户觉得Java没有前景,applets还只是个小玩意,菊花也还是一种花的时候吗?
我敢打赌下面至少有一半是你不清楚的。这周我们来看一下跟Java的内部实现相关的一些神奇的事情。
1. 其实根本没有受检查异常这回事
没错!JVM压根儿就不知道有这个东西,它只存在于Java语言里。
如今大家都承认受检查异常就是个错误。正如Bruce Eckel最近在布拉格的的GeeCON会议上所说的,除了Java外没有别的语言会使用受检查异常这种东西,即使是Java 8的新的Streams 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.<RuntimeException> doThrow0(e);
}
@SuppressWarnings("unchecked")
static <E extends Exception>
void doThrow0(Exception e) throws E {
throw (E) e;
}
}
|
这不仅能通过编译,而且也的确会抛出SQLException异常,并且完全不需要用到Lombok的@SneakyThrows注解。
更进一步的分析可以看下这篇
文章,或者Stack Overflow上的这个问题。
2. 不同的返回类型也可以进行方法重载
这个应该是编译不了的吧?
class Test {
Object x() { return "abc"; }
String x() { return "123"; }
}
是的。Java语言并不允许同一个类中出现两个重写等价("override-equivalent")的方法,不管它们的throws子句和返回类型是不是不同的。
不过等等。看下Java文档中的 Class.getMethod(String, Class...)是怎么说的。里面写道:
尽管Java语言不允许一个类中的多个相同签名的方法返回不同的类型,但是JVM并不禁止,所以一个类中可能会存在多个相同签名的方法。这添加了虚拟机的灵活性,可以用来实现许多语言特性。比如说,可以通过bridge方法来实现协变返回(covariant return,即虚方法可以返回子类而不一定得是基类),bridge方法和被重写的方法拥有相同的签名,但却返回不同的类型。
哇,这倒有点意思。事实上,下面这段代码就会触发这种情况:
abstract class Parent<T> {
abstract T x();
}
class Child extends Parent<String> {
@Override
String x() { return "abc"; }
}
看一下Child类所生成的字节码:
// Method descriptor #15 ()Ljava/lang/String;
// Stack: 1, Locals: 1
java.lang.String x();
0 ldc <String "abc"> [16]
2 areturn
Line numbers:
[pc: 0, line: 7]
Local variable table:
[pc: 0, pc: 3] local: this index: 0 type: Child
// Method descriptor #18 ()Ljava/lang/Object;
// Stack: 1, Locals: 1
bridge synthetic java.lang.Object x();
0 aload_0 [this]
1 invokevirtual Child.x() : java.lang.String [19]
4 areturn
Line numbers:
[pc: 0, line: 1
|
在字节码里T其实就是Object而已。这理解起来就容易多了。
synthetic bridge方法是由编译器生成的,因为在特定的调用点Parent.x()签名的返回类型应当是Object类型。如果使用了泛型却没有这个bridge方法的话,代码的二进制形式就无法兼容了。因此,修改JVM以支持这个特性貌似更容易一些(这顺便还实现了协变返回),看起来还挺不错 的吧?
你有深入了解过Java语言的规范和内部实现吗?这里有许多很有意思的东西。
English »
|
AfrikaansAlbanianArabicArmenianAzerbaijaniBasqueBengaliBelarusianBulgarianCatalanChinese (Simp)Chinese (Trad)CroatianCzechDanishDutchEnglishEsperantoEstonianFilipinoFinnishFrenchGalicianGeorgianGermanGreekGujaratiHaitian CreoleHebrewHindiHungarianIcelandicIndonesianIrishItalianJapaneseKannadaKoreanLaoLatinLatvianLithuanianMacedonianMalayMalteseNorwegianPersianPolishPortugueseRomanianRussianSerbianSlovakSlovenianSpanishSwahiliSwedishTamilTeluguThaiTurkishUkrainianUrduVietnameseWelshYiddish |
Options : History : Help : Feedback
Text-to-speech function is limited to 100 characters