- Java 8:Lambda 序列化?
- Java 8 lambda 最佳实践
- Java 8 lambda 表达式 10 个示例
- Java8 lambda 表达式 10 个示例
- Java8 Lambda 表达式和流操作如何让你的代码变慢 5 倍
- Java8:Lambda 表达式增强版 Comparator 和排序
- Java 8 LongAdders:管理并发计数器的正确方式
- Java 8 Optional 类深度解析
- Java8 中的 java.util.Random 类
- Java8 中的简易并发
- Java8 学习:Lambda 表达式、Stream API 和功能性接口 — 教程、资源、书籍和实例
- Java8 并发教程:Threads 和 Executors
- Java 8 新特性之旅:使用 Stream API 处理集合
- Java 8 新特性探究(一)通往 lambda 之路_语法篇
- Java 8 新特性探究(六)泛型的目标类型推断
- Java 8 新特性探究(七)深入解析日期和时间-JSR310
- Java 8 新特性探究(八)精简的 JRE 详解
- Java 8 新特性探究(九)跟 OOM:Permgen 说再见吧
- 总结
- Java 8 新特性探究(十)StampedLock 将是解决同步问题的新宠
- Java 8 新特性探究(十一)Base64 详解
- Java 8 新特性探究(十二)Nashorn :新犀牛
- Java 8 新特性终极指南
- Java 8 新的时间日期库的 20 个使用示例
- Java8 日期时间(Date Time)API 指南
- Java8 本地缓存
- Java 8 的 default 方法能做什么?不能做什么?
- Java 8 的 6 个问题
- Java 8 简明教程
- Java8 集合中的 Lambda 表达式
- Java SE 8 新的时间和日期 API
- 在 Java 8 下更好地利用枚举
- 在 Java 8 中避免 Null 检查
- 鲜为人知的 Java8 特性:泛化目标类型推断
鲜为人知的 Java8 特性:泛化目标类型推断
在浏览 Java8 的特性列表 的时候, 目标类型推断 这个特别有趣的、鲜为人知的特性一下子吸引了我。Java 语言的设计者通过它让我们减轻了一些使用泛型时(Java5-7)的痛苦。让我们来看看过去泛型使用的示例:
class List<E> {
static <Z> List<Z> nil() {..}
static <Z> List<Z> cons(Z head, List<Z> tail) {..}
E head() {..}
}
在上述例子,在 JEP:101 中声称可以用下面的方法更好地表示:
// 建议写法:
List.cons(42, List.nil());
String s = List.nil().head();
// 不推荐的写法:
List.cons(42, List.<Integer>nil());
String s = List.<String>nil().head();
作为一个 熟练的 API 设计师 ,在 Java 路线图中看到示例中的进步着实令人激动。这些令人兴奋的变化究竟包含了什么?让我来更加详细地说明:
// 通过赋值语句推断泛型的类型
List<String> l = List.nil();
// 更好的办法是让编译器从函数的参数类型中直接推断
List.cons(42, List.nil());
// 或者从“链式调用”中推断
String s = List.nil().head();
因此在上面的链式方法调用中,会延迟到整个赋值表达式完成时才进行类型推断。通过赋值语句左边,编译器会为 head()
调用推断;为 String
。然后,再次推断 nil()
调用的为 String
。 在我看来这真的很神奇。 对 nil()
方法的 AST 计算会延迟到“关联”子节点计算时才最后完成。这是一个很棒的主意,不是吗?
是的,确实很棒!
你可能也会这么认为。因为一组流畅的 API,像 jooq 或 Stream API 在设计时会考虑到这种调用的流畅性,在链式调用的最后才进行类型推断。为此,我下载了最新的 JDK 8 评估版本测试下面的程序:
public class InferenceTest {
public static void main(String[] args) {
List<String> ls = List.nil();
List.cons(42, List.nil());
String s = List.nil().head();
}
}
以下是得到的编译结果:
C:\Users\Lukas\java8>javac InferenceTest.java
InferenceTest.java:5: error: incompatible types:
Object cannot be converted to String
String s = List.nil().head();
^
1 error
从结果中可以看到,基于该方法参数的类型推断已经实现了(因此编译通过了),但是链式方法调用中的类型推断还没有实现。我在网上搜索到了一个解释,从 Stack OverFlow 问题 链接到 lambda-dev 开发者邮件列表 中。
看来,Java 类型系统已经变得相当复杂。由于太过复杂,要实现这种疯狂的类型推断变得不太现实。但是,每天编写 Java 8 代码的时候,即使略有改善也有重大的价值。
最后,希望在 Java 9 中会有 val
和 var 这样的关键字,与其他语言一样。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论