首页 存档 技术 查看内容

关于 Java 你不知道的 10 件事 官方微博:动力节点

2018-3-30 13:00 |来自: 互联网 299 0

摘要: 官方微博:动力节点 作为 Java 书呆子,比起实用技能,我们会对介绍 Java 和 JVM 的概念细节更感兴趣。因此我想推荐Lukas Eder 在jooq.org发表的原创作品给大家。 你是从很早开始就一直使用 Java 吗?那你还记得它 ...

官方微博:动力节点


作为 Java 书呆子,比起实用技能,我们会对介绍 Java 和 JVM 的概念细节更感兴趣。因此我想推荐Lukas Eder 在jooq.org发表的原创作品给大家。


你是从很早开始就一直使用 Java 吗?那你还记得它的过去吗?那时,Java 还叫 Oak,OO 还是一个热门话题,C 的 folk 者认为 Java 是不可能火起来,Java 开发的小应用程序 Applets 还受到关注。


我敢打赌,下面我要介绍的这些事,有一半你都不知道。下面让我们来深入探索 Java 的神秘之处。


1. 没有检查异常这种事情

没错!JVM 不会知道这些事情,只有 Java 语句知道。


如今大家都认为检查异常是个错误。正如Bruce Eckel 在布拉格 GeeCON 闭幕时所说,Java 之后再没别的语言检查异常,甚至 Java 8 在新的 Stream API 中也不再干这个事情(如果你的 Lambda 使用 IO 和 JDBC,这其实还是有点痛苦)。


如何证实 JVM 并不清楚检查异常一事?试试下面的代码:



这不仅可以编译通过,它还可以抛出 SQLException。

2. 你可以定义仅在返回值有差异的重载函数

这样的代码无法编译,对不?



对。 Java 语言不允许两个方法在同一个类中“等效重载”,而忽略其诸如throws自居或返回类型等的潜在的差异。


查看Class.getMethod(String,Class…)的 Javadoc。 其中说明如下:


来看看为Child 生成的字节码:



其实在字节码中T 真的只是 Object。这很好理解。


合成的桥方法实际是由编译器生成的,因为 Parent.x() 签名中的返回类型在实际调用的时候正好是 Object。在没有这种桥方法的情况下引入泛型将无法在二进制下兼容。因此,改变 JVM 来允许这个特性所带来的痛苦会更小(副作用是允许协变凌驾于一切之上) 很聪明,不是吗?

3. 所有这些都是二维数组!


是的,这是真的。即使你的大脑解析器不能立刻理解上面方法的返回类型,但其实他们都是一样的!类似的还有下面这些代码片段:



你认为这很疯狂?想象在上面使用JSR-308 / Java 8 类型注解。语法的可能性指数激增!



或者换句话说:


对你来说,上面的内容在你的实际使用中找到了吧。

4. 条件表达式的特殊情况

可能大多数人会认为:


是否等价于:


然而,事实并非如此。我们来测试一下就知道了。


由此可见,三目条件运算符会在有需要的情况下,对操作数进行类型提升。注意,是只在有需要时才进行;否则,代码可能会抛出 NullPointerException 空引用异常:


5. 你还没搞懂复合赋值运算符

很奇怪吗?来看看下面这两行代码:


现在看到它的作用了吗?我会在应用程序中对字符串进行乘法计算。因为,你懂的…

6. 随机整数

现在有一个更难的谜题。不要去看答案,看看你能不能自己找到答案。如果运行下面的程序:


这怎么可能?

. spoiler… 继续解答…


这必须通过反射重写 JDK 的 Integer 缓存,然后使用自动装箱和拆箱。不要在家干这种事情!或者,我们应该换种方式进行此类操作。

7. GOTO

这是我的最爱之一。Java也有GOTO!输入下试试……

7. GOTO

这是我的最爱之一。Java也有GOTO!输入下试试……



这是因为goto是一个未使用的关键字, 仅仅是为了以防万一……


但这不是最令人兴奋的部分。令人兴奋的部分是你可以使用 break、continue 和标记块来实现 goto 功能:


向前跳:

8. Java 有类型别名

其它语言(比如 Ceylon) 中,我们很容易为类型定义别名:



Java 中我们不能在顶层作用域定义类型别名,但是我们可以在类或方法作用域中干这个事情。假如我们不喜欢 Integer、Long 等等名称,而是想用更简短的 I 和 L,很简单:



在上面的程序中,Test 类作用域内 Integer 被赋予 I 这样的 “别名”,类似地,Long 在 x() 方法中被赋予 L 这样的 “别名”。之后我们可以这样调用方法:



这种技术当然不太会受重视。这种情况下,Integer 和 Long 都是 final 类型,也就是说,I 和 L 是事实上的别名(基本上赋值兼容性只需要考虑一种可能性)。如果我们使用非 final 类型 (比如 Object),那就是一般的泛型。


这些把戏已经玩够了。现在来看看真正了不起的东西!

9. 某些类型的关系并不确定!

好了,这会很引人注目,先来杯咖啡提提神。思考一下下面两个类型:


非常难回答的问题,不过Ross Tate已经回答了。这个问题的答案是不可判定的:

C 是 Type

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部