不少初学Java的小伙伴常常咨询:java
是这样,官网如今其实都已经出到Java 13版本了,而且提供下载使用。python
但目前市场上主流的稳定版固然还得属Java 8和Java 11,而目前大部分公司的生产环境仍是Java 8
居多。因此若是从自学角度出发,我以为这两个版本都OK,其余中间的一些好比Java 9
、Java 10
这些非稳定版就不用考虑了。编程
Java 11相对于Java 8确实有一部分进化,除了有不少内部的升级(好比开销和时延更低的GC、TLS1.3加持等等)以外,对于初学使用者来讲也有一些语言使用层面的进化。oracle
正好最近我在本身的我的小项目上尝试升级使用了一下Java 11
(公司项目咱也不敢动、也不敢问,只好动本身的我的项目),所以本文从实际代码编写角度来大体体验一下我我的使用Java 11
以后相对Java 8
所感受到的一些比较深入的进化,官方文档里说得也很是清楚了:https://docs.oracle.com/en/java/javase/11/
异步
我此次实验装的Java 11
版本是11.0.6
:函数式编程
下文将要实验验证的一些新特性其实也并不是Java 11
才引入,不少其实在Java 9
和Java 10
时就已经引入,只不过到了Java 11
这个稳定版才沉淀下来。
新版Java引入了一个全新的类型关键字var
,用var
来定义的变量不用写具体类型,编译器能根据=
右边的实际赋值来自动推断出变量的类型:函数
一、普通局部变量ui
var name = "codesheep"; // 自动推断name为String类型 System.out.println(name);
怎么样?是否是有一种在使用相似JavaScript这种弱类型语言的错觉?
二、for循环中使用this
var upList1 = List.of( "刘能", "赵四", "谢广坤" ); var upList2 = List.of( "永强", "玉田", "刘英" ); var upList3 = List.of( "谢飞机", "兰妮", "兰娜" ); var upListAll = List.of( upList1, upList2, upList3 ); for( var i : upListAll ) { // 用var接受局部变量的确很是简洁! for( var j : i ) { System.out.println(j); } }
这地方就能看出用var
定义局部变量的优点了,假如这个例子中集合里的元素类型更为复杂,是相似List<List<String>>
这种嵌套类型的话,var
定义就很是简洁明了!spa
三、固然,有些状况是不能使用的
var
类型变量一旦赋值后,从新赋不一样类型的值是不行的,好比:
var name = "codesheep"; name = 666; // 此时编译会提示不兼容的类型
定义var
类型变量没有初始化是不行的,好比:
var foo; // 此时编译会提示没法推断类型 foo = "Foo";
另外,像类的成员变量类型
、方法入参类型
、返回值类型
等是不能使用var
的,好比:
public class Test { private var name; // 会提示不容许使用var public void setName( var name ) { // 会提示不容许使用var this.name = name; } public var getName() { // 会提示不容许使用var return name; } }
是的!
如今JDK
官方就自带HTTP Client
了,位于java.net.http
包下,支持发送同步、异步的HTTP
请求,这样一来,之前我们经常使用的HTTP请求客户端诸如:OKHttp
、HttpClient
这种如今均可以退下了!
发送同步请求:
var request = HttpRequest.newBuilder() .uri( URI.create("https://www.codesheep.cn") ) .GET() .build(); // 同步请求方式,拿到结果前会阻塞当前线程 var httpResponse = HttpClient.newHttpClient() .send( request, HttpResponse.BodyHandlers.ofString()); System.out.println( httpResponse.body() ); // 打印获取到的网页内容
发送异步请求:
CompletableFuture<String> future = HttpClient.newHttpClient(). sendAsync( request, HttpResponse.BodyHandlers.ofString() ) .thenApply( HttpResponse::body ); System.out.println("我先继续干点别的事情..."); System.out.println( future.get() ); // 打印获取到的网页内容
固然你也能够自定义请求头,好比携带JWT Token
权限信息去请求等:
var requestWithAuth = HttpRequest.newBuilder() .uri( URI.create("http://www.xxxxxx.com/sth") ) .header("Authorization", "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiIxNTIwNTE2MTE5NiIsImNyZWF0ZWQiOjE1ODMzMTA2ODk0MzYsImV4cCI6MTU4MzM5NzA4OSwidXNlcmlkIjoxMDAwNH0.OE9R5PxxsvtVJZn8ne-ksTb2aXXi7ipzuW9kbCiQ0uNoW0fJJr_wckLFmgDzxmBs3IdzIhWDAtaSIvmTshK_RQ") .GET() .build(); var response = HttpClient.newHttpClient() .send( requestWithAuth, HttpResponse.BodyHandlers.ofString() ); System.out.println( response.body() ); // 打印获取到的接口返回内容
新版字符串String
类型增长了诸如:isBlank()
、strip()
、repeat()
等方便的字符串处理方法
String myName = " codesheep "; System.out.println( " ".isBlank() ); // 打印:true System.out.println( " ".isEmpty() ); // 打印:false System.out.println( myName.strip() ); // 打印codesheep,先后空格均移除 System.out.println( myName.stripLeading() ); // 打印codesheep ,仅头部空格移除 System.out.println( myName.stripTrailing() ); // 打印 codesheep,仅尾部空格移除 System.out.println( myName.repeat(2) ); // 打印 codesheep codesheep
主要是增长了诸如of()
和copyOf()
等方法用于更加方便的建立和复制集合类型
var upList = List.of( "刘能", "赵四", "谢广坤" ); var upListCopy = List.copyOf( upList ); System.out.println(upList); // 打印 [刘能, 赵四, 谢广坤] System.out.println(upListCopy); // 打印 [刘能, 赵四, 谢广坤] var upSet = Set.of("刘能","赵四"); var upSetCopy = Set.copyOf( upSet ); System.out.println(upSet); // 打印 [赵四, 刘能] System.out.println(upSetCopy); // 打印 [赵四, 刘能] var upMap = Map.of("刘能","58岁","赵四","59岁"); var upMapCopy = Map.copyOf( upMap ); System.out.println(upMap); // 打印 {刘能=58岁, 赵四=59岁} System.out.println(upMapCopy); // 打印 {刘能=58岁, 赵四=59岁}
我印象最深的是对Stream
流增长了诸如takeWhile()
和dropWhile()
的截止结算方法:
var upList = List.of( "刘能", "赵四", "谢广坤" ); // 从集合中依次删除知足条件的元素,直到不知足条件为止 var upListSub1 = upList.stream() .dropWhile( item -> item.equals("刘能") ) .collect( Collectors.toList() ); System.out.println(upListSub1); // 打印 [赵四, 谢广坤] // 从集合中依次获取知足条件的元素,知道不知足条件为止 var upListSub2 = upList.stream() .takeWhile( item -> item.equals("刘能") ) .collect( Collectors.toList() ); System.out.println( upListSub2 ); // 打印 [刘能]
一、Files类加强
咱们之前心心念的直接能把文件内容读取到String
以及String
回写到文件的功能终于支持了,能够经过Files
类的静态方法writeString()
和readString()
完成:
Path path = Paths.get("/Users/CodeSheep/test.txt"); String content = Files.readString(path, StandardCharsets.UTF_8); System.out.println(content); Files.writeString( path, "王老七", StandardCharsets.UTF_8 );
二、InputStream加强
InputStream
则增长了一个transferTo()
方法,直接将数据丢到OutputStream
去:
InputStream inputStream = new FileInputStream( "/Users/CodeSheep/test.txt" ); OutputStream outputStream = new FileOutputStream( "/Users/CodeSheep/test2.txt" ); inputStream.transferTo( outputStream );
好比我写一个最简单的Hello World
程序:
public class Hello { public static void main( String[] args ) { System.out.println("hello world"); } }
并保存为hello.java
文件,这时候能够直接用java
指令去运行这个Java源文件,直接省去之前javac
编译源文件的过程:
java hello.java
怎么样?是否是和python源文件的运行有点像?这个信息量就有点大了,你们能够自行脑补一下
Java 11确有不少改进,但仍是那句话,对于初学者来讲Java 8了,不必刻意求新,稳才是最重要的!