WeTest腾讯质量开发平台 程序员要拥抱变化,聊聊 Android 即将支持的 Java 8

腾讯WeTest · 2017年05月05日 · 最后由 bauul 回复于 2017年05月16日 · 3903 次阅读
本帖已被设为精华帖!

原文链接:http://wetest.qq.com/lab/view/308.html
商业转载请联系腾讯 WeTest 获得授权,非商业转载请注明出处。

WeTest 导读

Java 9 预计今年也会正式发布,Java 8 这个最具变革性且变革性最适于 GUI 程序的版本,Android 终于准备正式支持。从自己开发 JavaFx 的感受,说一说 Java 8 应该使用的新特性。程序员,你应该拥抱变化。(注:本文不讲具体语法,具体语法请下载下方分享的《Java 8 实战》。)


James Lau(google 的产品经理):We’ve decided to add support for Java 8 language features directly into the current javac and dx set of tools, and deprecate the Jack toolchain. With this new direction, existing tools and plugins dependent on the Java class file format should continue to work. Moving forward, Java 8 language features will be natively supported by theAndroid build system.

我们决定弃用 Jack 工具链,改为直接在最新的 javac 和 dx 工具集中增加对 Java 8 语言功能的支持。经过这番改弦易辙,依赖于 Java 类文件格式的现有工具和插件仍可继续工作。今后,Java 8 语言功能将得到 Android 构建系统的原生支持。

一、GUI 桌面类软件特点

GUI 图形界面的应用程序有几个特点:

● 基于消息驱动模型

● 强交互,实时性要求高

● 用户触发执行与用户触发结束

二、Lambda 表达式

举个实际应用中的例子,下面这部分的代码是过滤出某个目录下所有 xml 后缀的文件,java 8 之前的写法是这样子的:

Java 8 的写法
这里写图片描述

lambda 需要解决的一个核心问题啰嗦,lambda 能做的内部类都能做。Java 是面向对象的语言,不支持方法。C 语言的方法,在 java 里面可能是一个接口,可能是一个静态方法。listFiles 这个方法需要的是一个行为(行为参数化,更高级的抽象),这个行为是 name.endsWith(“.xml”),但是 java 不支持传递行为方法。所以,java 8 之前我们不得不用函数接口(只包含一个方法的接口,专有名词函数接口)对象的方式来对行为进行包装。刻薄的讲 FileTypeFilter 类命名为 FilenameFilterActionWrapper 更加贴切。

1、方法引用

Lambda 有一种快捷写法,方法引用。之前说,在 Java 中定义方法的方式,一种是接口,一种是静态方法,现有的库中已经包含有大量的方法。方法引用,可以让我们重用这些方法,让这些方法像 Lambda 一样能够被传递。

GUI 程序中的用法,这种写法 Java 8 之前,在 JavaFx 或者 Android 程序中都应该会大量出现

Java 8 之后的写法应该是这样的

这两者的差别,解释起来应该是这样子的。本质:” 直接调用这个方法”,Lambda 或者 java 8 之前” 描述如何调用这个方法”。你没必要再去描述如何调用,因为都知道该怎么调用。我们知道 GUI 程序最基本的设计时 MVC,解决的是视图和逻辑分离,这几乎是 GUI 程序设计里面最基本的。逻辑处理方法一般并不会包含在控制器的类里面,而是在逻辑层,有了方法引用你可以直接与逻辑层的方法相关联。

2、为什么要 lambda

● 简洁的代码,跟利于行为参数化(高级抽象,if else->参数化 - 行为参数化)

● 预设的 lambda 接口,Predicate、Consumer、Function 等,java 8 大量库支持。如果你不理解 lambda,你将不理解大量 Java 8 的接口。

● 类型检查、类型推断更优

注:写 lambda 的时候,参数一定要有含义,本来就不写类型了,再不写有含义的变量就真的是天书了。

三、CompetableFuture 组合式异步编程

一个解析 Android apk 信息的类,可能会解析很长一段时间,所以需要有超时。
Java 5 之前的写法

Java 5 的写法

Java 8

那么 CompletableFuture 除了少些几句代码之外,它到底有什么好处呢?

● 约定:与设计模式一样,这是程序员的一种约定。接口返回 CompletableFuture,调用者一眼就只这是个异步 API,也知道如何调用它

● 同步转异步:配合 lambda,几句话就能完成。

● 异常传递:apkInformation.completeExceptionally(new WeTestRuntimeException(e.getMessage(), e)),其他线程的异常可以传递过来。GUI 程序里面,异常通常要转化为用户的一种视图。

● 协调:等待多个异步操作完成合并(如查找多家网站酒店价格,取最小值),等待多个异步操作中最快的一个完成,异步操作完成后回调一个函数(异步操作完成,来个 Toast)。在以前这些协调性的功能,可能需要借助 CountDownLatch,CyclicBarrier 来完成。CompletableFuture 一步到位

注:CompletableFuture 配合 Stream 可以极大的提高并发的效率

举个简单的上面这个例子返回后的用法:

四、Stream 流处理

Use stream operations to express refined data processing queries.用流 Stream 以表达式的方式来完成数据处理。我自己的理解是,以数据库的操作方式来完成数据的处理。Java 8 的 Stream 内置了许多类似于数据库的操作 filter、sort、map、reduce 等。
Stream 优点:

● 以数据库操作数据的方式,专注于如何做这个某个步骤,表达式的方式

● 高并发(看到 map、reduce 就应该能想到了)

举个用法的例子,业务时获取所有在线的可测试的手机:

注:Stream 的写法的确对原因的思维方式会造成一定的冲击,不过写过了,加上有一定数据库使用基础的话理解起来非常容易。Stream 高性能的特点的确感受不深,因为处理大量数据的情况毕竟是少数。

五、Optional

A container object which may or may not contain a non-null value.一个可能包含 null 指的对象包装器。null 不可避免,能避免的是 NullPointerException。null 最大的罪在于它可以代表任何类型。下面这两个接口,不去看你的注释,我并不知道你是否可能会返回 null。在业务需求变化如此快的今天,贴切非常容易出现对返回值不做检查的情况,任何人都会偷懒。Optional 的处理逻辑是,强迫你去检查。如果我的返回值是 Optional,这个接口显式的告诉你可能返回的是 null 值,这个在 GUI 程序里面特别常见。

GUI 的弹出框用户可能并不填内容内容,返回 null。

所以,Optional 的核心思想就是我明确告诉你可能会返回 null,你一定要处理。所以,现在模块间提供给其他人的接口,如果有可能返回为 null 都要声明为 Optional。Java 8 大量的官方接口也都会放回 Optional,这个是一定要学的内容。

Java 8 实战:https://share.weiyun.com/075e6cd0f306c706260fb377c38ac90b


近日,谷歌发布了安卓 8.0 开发者预览版。腾讯 WeTest 立刻在云真机产品中增加了带有安卓 O 系统的真机。

想要率先体验的用户可以登录:http://wetest.qq.com/product/cloudphone

如在使用中有任何疑问,欢迎联系企业 qq:800024531

共收到 2 条回复 时间 点赞
恒温 将本帖设为了精华贴 05月06日 23:31

java 有点焕发青春的感觉么~

赞,扫盲了

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册