深入探索Java 9新特性与REPL实践

本文详细介绍了Java 9在Java With The Best 2018大会上的技术分享,重点探讨了JShell REPL工具的使用,涵盖集合、流、CompletableFuture等API更新,以及StackWalker、ProcessHandle等新特性,通过大量实际代码示例展示Java 9的技术革新。

Java With The Best 2018大会上的Java 9技术分享

Java With The Best是由BeMyApp主办的一系列开发者会议中的新Java会议。这个活动有两个主要特点使其与其他会议不同——所有活动都在线上进行,没有实体场地,与会者可以与演讲者预订虚拟一对一会议。该活动包含3个主要轨道(核心Java;大数据、机器学习和云;框架、库和语言)的58个演讲,以及一个额外的Java社区演讲者轨道。我受邀在核心Java轨道中分享关于Java 9的内容。

在题为"使用REPL探索Java 9"的会议中,我们深入研究了JShell,并使用它来探索Java 9中一系列值得注意的特性。我们涵盖了4个现有API的更新——集合、流、CompletableFuture和Optional,以及Java 9中4个全新的API——Stackwalker、ProcessHandle、HTTP/2客户端和JShell本身。与我的大多数演讲一样,这是一个现场编码会议,包含大量Java示例。

虚拟会议体验

这是我第一次在虚拟会议上发言,这是一次有趣的经历。作为演讲者,我们可以在活动前几天测试会议平台,确保硬件支持,并在实际演讲时一切顺利运行。但也出现了一些挑战:平台只允许共享整个屏幕,而不是特定窗口;与会者无法通过视频或音频连接,但可以在会议网站上的对话框中输入问题;平台不太适合笔记本电脑使用和现场编码。

经过调整后,演讲进行得非常顺利。我观看了其他几个演讲,总体上很享受这次会议。

会议资源

会议进行了直播,录制内容已上线。虽然不免费提供,但现在活动结束后,您可以花费15美元获取所有会议内容。

幻灯片可在线获取(下载链接):

  • 使用REPL探索Java 9 - Miro Cupak

如果您想自己尝试示例,请随意使用我的JShell会话导出:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
1+1
int x = 1+1
System.out.println(x)
Thread.sleep(2000)
/vars
/types
int inc(int x) { return x+1; }
inc(5)
/list
/l
/help
Set<String> set = new HashSet<String>()
set.add("a")
set.add("b")
set.add("c")
Collections.unmodifiableSet(set)
List<Integer> list = List.of(1,2,3)
list.add(4)
list.getClass()
Map.ofEntries(entry(1, "hello"))
IntStream.range(0, 10).forEach(System.out::println)
IntStream.range(0, 10).limit(5).forEach(System.out::println)
IntStream.range(0, 10).skip(5).forEach(System.out::println)
IntStream.range(0, 10).takeWhile(x -> x<5).forEach(System.out::println)
IntStream.range(0, 10).dropWhile(x -> x<5).forEach(System.out::println)
IntStream.iterate(0, i -> i+2).filter(j -> j<100).forEach(System.out::println)
IntStream.iterate(0, i -> i<100, i -> i+2).forEach(System.out::println)
Stream.of(1)
Stream.of(null)
Stream.ofNullable(null)
Stream.ofNullable(null).count()
Optional.empty()
Optional.of("something")
Optional.of("something").ifPresent(System.out::println)
Optional.empty().ifPresent(System.out::println)
Optional.empty().ifPresentOrElse(System.out::println, () -> System.out.println("empty"))
Optional.empty().orElse("empty")
Optional.empty().orElseGet(() -> "empty")
Optional.empty().or(() -> Optional.of("empty"))
Optional.of("something").or(() -> Optional.of("empty"))
Optional.of("something").stream().forEach(System.out::println)
Optional.empty().stream().forEach(System.out::println)
CompletableFuture<String> cf = new CompletableFuture<String>()
cf.complete("done")
cf.get()
CompletableFuture<String> cf = new CompletableFuture<String>()
cf.get()
cf.completeExceptionally(new IllegalStateException())
cf.get()
CompletableFuture<String> cf = new CompletableFuture<String>()
cf.completeOnTimeout("timed out", 5, TimeUnit.SECONDS)
cf
cf
cf
cf.get()
CompletableFuture<String> cf = new CompletableFuture<String>()
cf.orTimeout(5, TimeUnit.SECONDS)
cf
cf
cf.get()
CompletableFuture<String> cf = new CompletableFuture<String>()
CompletableFuture<String> copy = cf.copy()
cf
copy
cf.complete("done")
copy
copy.get()
CompletableFuture<String> cf = new CompletableFuture<String>()
CompletableFuture<String> copy = cf.copy()
copy.complete("done")
copy
cf
StackTraceElement[] st = new Throwable().getStackTrace()
st
StackWalker.getInstance().walk(s -> s.collect(Collectors.toList()))
StackWalker.getInstance().walk(s -> s.limit(3).collect(Collectors.toList()))
StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).walk(s -> s.map(f -> f.getDeclaringClass()).collect(Collectors.toList()))
StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).walk(s -> s.map(f -> f.getDeclaringClass()).filter(c -> c.equals(jdk.jshell.execution.Util.class)).collect(Collectors.toList()))
new ProcessBuilder().command("jps").start()
ProcessHandle.current().pid()
ProcessHandle.current().info()
ProcessHandle.current().info().commandLine()
ProcessHandle.allProcesses().map(p -> p.info().command()).collect(Collectors.toList())
new ProcessBuilder().command("sleep", "3").start().toHandle().onExit().thenAccept(System.out::println)
ProcessBuilder jps = new ProcessBuilder().command("jps")
ProcessBuilder grep = new ProcessBuilder().command("grep", "JShell")
List<Process> pipeline = ProcessBuilder.startPipeline(List.of(jps,grep))
pipeline
new BufferedReader(new InputStreamReader(pipeline.get(1).getInputStream())).readLine()
HttpHandler handler = he -> {
    String body = "hello jwtb";
    he.sendResponseHeaders(200, body.length());
    try (OutputStream os = he.getResponseBody()){
        os.write(body.getBytes());
    }
}
/l handler
HttpServer hs = HttpServer.create(new InetSocketAddress(8000), 0)
hs.createContext("/hello", handler)
hs.start()
URI uri = new URI("http://localhost:8000/hello")
HttpURLConnection c = (HttpURLConnection) uri.toURL().openConnection()
c.setRequestMethod("GET")
c.getResponseCode()
new BufferedReader(new InputStreamReader(c.getInputStream())).readLine()
HttpClient client = HttpClient.newHttpClient()
HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build()
HttpResponse<String> response = client.send(request, BodyHandler.asString())
response.statusCode()
response.body()
CompletableFuture<HttpResponse<String>> response = client.sendAsync(request, BodyHandler.asString())
response.get().body()
JShell js = JShell.create()
List<SnippetEvent> events = js.eval("1+1")
js.variables().forEach(System.out::println)
events.stream().map(e -> e.status()).forEach(System.out::println)
events.stream().map(e -> e.snippet().source()).forEach(System.out::println)
events.stream().map(e -> e.value()).forEach(System.out::println)
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计