java9正式发布已经有一段时间了,作为一个思想激进__开放__,勇于探索的喵,本着拥抱新特性的心态。第一时间对java的文档进行了拜读,结合这段时间零零散散__持续__的测试和理解,记录下来以后可能会用到的几个特性。
JShell
Java 9 中引入了交互式编程环境(REPL),这就是JShell。JShell可以执行Java代码,并且立即返回执行结果。可以用来测试一些简单的方法,函数以及算法。本喵或许可以告别创建一个Text.java然后写一个main方法来测试一些函数的做法,使用JShell可以快速地执行代码,节省了项目编译的时间。付出的代价就是需要多多练习脱离IDE码代码的技能了。
使用方法:安装好Java9并配置好运行环境后,在命令行输入
BOBOdeRMBP:~ bobo$ java -version
java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)
BOBOdeRMBP:~ bobo$ jshell
| 欢迎使用 JShell -- 版本 9
| 要大致了解该版本, 请键入: /help intro
jshell>
即可进入JShell。
测试一下基本功能。声明一个int类型的变量,并未这个变量赋值。然后打印出变量信息。
jshell> int i = 10
i ==> 10
jshell> System.out.print("i:"+i)
i:10
jshell>
查看更多介绍。。。
不可变集合类的工厂方法
在处理多线程操作数据时,大多数时候数据线程安全和脏数据问题都会被掩盖。在Java8以及更早版本,我们创建一个不可变集合对象时通常使用Collections.unmodifiableXXX的方法。当我们需要初始化这样一个不可变集合的时候就显得比较麻烦了。
在Java9中,Oracle引用了一些非常方便的工厂方法可以用来创建各种不可变集合。
//空list 9 befor
List emptylist = Collections.EMPTY_LIST;
//空list 9
List emptylist9 = List.of();
//非空list 9 befor
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
List notEmptylist = Collections.unmodifiableList(list);
//非空list 9
List<String> notEmptylist9 = List.of("a", "b", "c", "d", "e");
//空map 9 befor
Map emptyMap = Collections.EMPTY_MAP;
//空map 9
Map emptyMap9 = Map.of();
//非空map 9 befor
Map<String, String> map = new HashMap<>();
map.put("a", "this is a");
map.put("b", "this is b");
map.put("c", "this is c");
map.put("d", "this is d");
Map<String, String> notEmptyMap = Collections.unmodifiableMap(map);
//非空map 9
Map<String, String> map1 = Map.of("a", "this is a", "b", "this is b", "c", "this is c", "d", "this is d");//这种写法最大支持10个键值对
Map<String, String> map2 = Map.ofEntries(Map.entry("a", "this is a"), Map.entry("b", "this is b"), Map.entry("c", "this is c"), Map.entry("d", "this is d"));
//set略
接口的私有方法
在Java8中,接口中可以定义模式实现和静态方法。但是不能创建私有方法。为了避免冗余代码和提高重用性,Java9现在支持定义私有方法,声明使用的方式与普通类中的一致。进一步提高代码复用率。举个🌰
//Dog.java
public interface Dog {
static void barking() {
System.out.println("汪汪汪");
}
private static void cry() {
System.out.println("呜呜呜");
}
default void sad() {
cry();
}
void play();
}
//Husky.java
public class Husky implements Dog {
@Override
public void sad() {
System.out.println("我不哭,我拆家");
}
@Override
public void play() {
Dog.barking();
System.out.println("不管怎么样都疯狂撒欢");
}
}
//GoldenRetriever.java
public class GoldenRetriever implements Dog {
@Override
public void play() {
System.out.println("不管怎么样都非常开心");
Dog.barking();
}
}
//main.java
public static void main(String[] args) {
Husky husky = new Husky();
husky.sad();
husky.play();
GoldenRetriever goldenRetriever = new GoldenRetriever();
goldenRetriever.sad();
goldenRetriever.play();
}
1.定义Dog接口抽象狗子们的行为。抽象的结果:所有狗子需要玩(play)但是表现不一样。所有狗子都会叫(barking)而且都是“汪汪汪”。
狗子们会伤心(sad),大部分狗子伤心都会哭(cry),个别例外。
2.具体实现狗子,先实现二哈Husky。二哈伤心的时候是例外,独立实现了伤心的方法。play的实现是撒欢,并且像所有狗子一样叫。然后实现金毛GoldenRetriever。金毛伤心时和大部分狗子一样会哭。play的实现是开心,并且像所有狗子一样叫。
叫(barking)是所有对象共有的特征,抽象成接口的静态方法,允许所有的实现内部调用。
伤心(sad)是大部分对象的共同特征,可以在接口抽象出默认实现,个例独立实现。
哭泣(cry)是内部接口抽取的公共代码,会被伤心(sad)等其它接口内部方法调用。
Java9的接口允许定义
| 支持 | 是否可外部引用 | 是否可实现/重写 |
|---|---|---|
| 常量变量 | ✅ | ❌ |
| 抽象的方法 | ❌¿ | ✅ |
| 默认的方法 | ✅ | ✅ |
| 静态方法 | ✅ | ❌ |
| 私有方法 | ❌ | ❌ |
| 私有静态方法 | ❌ | ❌ |
Stream增强
Stream作为Java8的一大亮点,它与java.io包里的InputStream和OutputStream是完全不同的概念。它也不同于StAX对XML解析的Stream,也不是AmazonKinesis对大数据实时处理的Stream。Java8中的Stream是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregateoperation),或者大批量数据操作(bulkdataoperation)。StreamAPI借助于同样新出现的Lambda表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用fork/join并行方式来拆分任务和加速处理过程。通常编写并行代码很难而且容易出错,但使用StreamAPI无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java8中首次出现的java.util.stream是一个函数式语言+多核时代综合影响的产物
Java9对Stream操作又进行了进一步强化。Stream接口中添加了4个新的方法:dropWhile,takeWhile,ofNullable。还有个iterate方法的新重载方法。
iterate的重载方法方法提供了一个Predicate来指定什么时候结束,在Java8中,使用limit方法来约束iterate返回的Stream的长度。下面是三段等价代码
Stream.iterate(1, i -> i < 200, i -> i + 2).forEach(System.out::println);
Stream.iterate(1, i -> i + 2).limit(100).forEach(System.out::println);
for (int i = 1; i < 200; i += 2) {
System.out.println(i);
}
dropWhile和takeWhile,废话不多说,直接上代码
List<Integer> list = new ArrayList<>();
Stream.iterate(1, i -> i < 10, i -> i + 1).forEach(list::add);
Stream.iterate(1, i -> i < 10, i -> i + 1).forEach(list::add);
list.forEach(System.out::print);
System.out.println();
list.stream().dropWhile(s -> s < 5).forEach(System.out::print);
System.out.println();
list.stream().takeWhile(s -> s < 5).forEach(System.out::print);
//输出结果
// 123456789123456789
// 56789123456789
// 1234
dropWhile和takeWhile和filter方法相似但不相同。
filter方法验证Stream中的每一个元素。
dropWhile方法对于有序流,从断言指定为true的起始处丢弃元素。当输出条件为小于5时返回true,使用dropWhile会删除前4个元素。对于无序流dropWhile方法的行为是非确定性的。它可以选择删除匹配条件的任何元素子集。当前的实现从匹配元素开始丢弃匹配元素,直到找到不匹配的元素。dropWhile方法有两种极端情况。如果第一个元素与predicate不匹配,则该方法返回原始流。如果所有元素与predicate匹配,则该方法返回一个空流。
takeWhile方法的工作方式与dropWhile方法相同,只不过它从流的起始处返回匹配的元素,而丢弃其余的。
Java8中Stream不能包含null,否则会报空指针异常,而Java9中的ofNullable方法允许我们创建一个单元素Stream,可以包含一个非空元素,也可以创建一个空Stream。
Stream<String> stream = Stream.ofNullable("hello,world");
System.out.println(stream.count());
//jshell 执行结果 1
stream = Stream.ofNullable(null);
System.out.println(stream.count());
//jshell 执行结果 0
改进应用安全性能
Java9新增了4个SHA-3哈希算法,SHA3-224、SHA3-256、SHA3-384和SHA3-512。另外也增加了通过java.security.SecureRandom生成使用DRBG算法的强随机数。
final MessageDigest instance = MessageDigest.getInstance("SHA3-224");
final byte[] digest = instance.digest("".getBytes());
System.out.println(Hex.encodeHexString(digest));
进程API
Java9增加了ProcessHandle接口,可以对原生进程进行管理,尤其适合于管理长时间运行的进程。在使用ProcessBuilder来启动一个进程之后,可以通过Process.toHandle()方法来得到一个ProcessHandle对象的实例。通过ProcessHandle可以获取到由ProcessHandle.Info表示的进程的基本信息,如命令行参数、可执行文件路径和启动时间等。ProcessHandle的onExit()方法返回一个CompletableFuture
final ProcessBuilder processBuilder = new ProcessBuilder("top")
.inheritIO();
final ProcessHandle processHandle = processBuilder.start().toHandle();
processHandle.onExit().whenCompleteAsync((handle, throwable) -> {
if (throwable == null) {
System.out.println(handle.pid());
} else {
throwable.printStackTrace();
}
});
以上简单说一下Java9中语法的新特性,Java9的特性还包括Project Jigsaw(平台模块系统),http 2,I/O流新特性等等。后面本喵会逐步理解分析Java9中优秀的概念设计,希望能尽快享受Java9带来的工作便利。