-
3-10 JDK11 中新增加的常用 API
查看全部 -
JEP 323:Lambda参数的本地变量语法
http://openjdk.java.net/jeps/323
摘要
允许
var
在声明隐式类型的lambda表达式的形式参数时使用。目标
将隐式类型的lambda表达式中的形式参数声明的语法与局部变量声明的语法对齐。
非目标
将任何其他类型的变量声明(例如,方法的形式参数)的语法与局部变量声明的语法对齐。
动机
一个lambda表达式可以被隐式类型,其中类型的所有形式参数都推断出:
(x, y) -> x.process(y) // implicitly typed lambda expression
Java SE 10使隐式类型可用于局部变量:
var x = new Foo(); for (var x : xs) { ... } try (var x = ...) { ... } catch ...
为了与局部变量保持一致,我们希望允许'var'用于隐式类型的lambda表达式的形式参数:
(var x, var y) -> x.process(y) // implicit typed lambda expression
统一性的一个好处是修饰符,特别是注释,可以应用于局部变量和lambda形式,而不会失去简洁性:
@Nonnull var x = new Foo(); (@Nonnull var x, @Nullable var y) -> x.process(y)
描述
对于隐式类型的lambda表达式的形式参数,允许使用保留的类型名称
var
,以便:(var x, var y) -> x.process(y)
相当于:
(x, y) -> x.process(y)
隐式类型的lambda表达式必须
var
用于其所有形式参数,或者不能用于任何形式参数。此外,var
仅允许隐式类型化lambda表达式的形式参数---显式类型化的lambda表达式继续为其所有形式参数指定清单类型,因此某些形式参数不允许其他人使用清单类型var
。以下示例是非法的:(var x, y) -> x.process(y) // Cannot mix 'var' and 'no var' in implicitly typed lambda expression (var x, int y) -> x.process(y) // Cannot mix 'var' and manifest types in explicitly typed lambda expression
从理论上讲,有一个lambda表达式可能就像上面的最后一行一样,它是半显式类型(或半隐式类型,取决于你的观点)。但是,它超出了此JEP的范围,因为它会深刻影响类型推断和重载决策。这是保持lambda表达式必须指定所有清单参数类型或不指定的限制的主要原因。我们还希望强制推断隐式类型化lambda表达式的参数的类型是否相同无论是否
var
使用。我们可能会在未来的JEP中回到局部推断的问题。此外,我们不希望损害简写语法的简洁性,因此我们不允许使用以下表达式:var x -> x.foo()
查看全部 -
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>11</release> </configuration> </plugin> </plugins> </build>
查看全部 -
import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.util.concurrent.CompletableFuture; /** * 标准HTTP客户端 */ public class HttpClientExample { /** * 同步Get方法 * @param uri * @throws Exception */ private static void synGet(String uri) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder().uri( URI.create(uri)).build(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.statusCode()); System.out.println(response.body()); } /** * 异步Get方法 * @param uri * @throws Exception */ private static void asyncGet(String uri) throws Exception { HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder().uri( URI.create(uri)).build(); CompletableFuture<HttpResponse<String>> future = client.sendAsync(request,HttpResponse.BodyHandlers.ofString()); future.whenComplete((resp,ex)->{ if (ex!=null){ ex.printStackTrace(); }else { System.out.println(resp.statusCode()); System.out.println(resp.body()); } }).join(); } public static void main(String[] args) throws Exception { String uri = "http://t.weather.sojson.com/api/weather/city/101030100"; //synGet(uri); asyncGet(uri); } }
查看全部 -
methodhandler相较于反射更轻量级:
1.本质上讲两个都是在模拟方法的调用,但Reflection是模拟java代码层次的调用,而MethodHandle是模拟的字节码层次的,上面的例子中是模拟的invokevirtual指令。
2.Reflection是重量级的,而MethodHandle是轻量级的。
最重要的是,Reflection 只为java服务,而MethodHandle则可以服务于所有的运行在java虚拟机上的语言。
public class MethodHandlerTest { static class A { public void println(String s) { System.err.println("i am class A:" + s); } } public static void main(String[] args) throws Throwable { Object object = System.currentTimeMillis() % 2 == 0 ? System.out : new A(); //无论 object是要那个实现类,下面的都能正确调用 到println方法 getPrintlnMh(object).invokeExact("lisj"); } private static MethodHandle getPrintlnMh(Object target) throws Exception { MethodType methodType = MethodType.methodType(void.class, String.class); return MethodHandles.lookup().findVirtual(target.getClass(), "println", methodType).bindTo(target); } }
查看全部 -
jdk11之前的版本通过反射访问private修饰的属性成员需field.setaccessable(),而jdk11则不需要设置
查看全部 -
https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.4.4
表4.4-B。常量池标签(按标签)
常数种类 标签 class
文件格式Java SE CONSTANT_Utf8
1 45.3 1.0.2 CONSTANT_Integer
3 45.3 1.0.2 CONSTANT_Float
4 45.3 1.0.2 CONSTANT_Long
五 45.3 1.0.2 CONSTANT_Double
6 45.3 1.0.2 CONSTANT_Class
7 45.3 1.0.2 CONSTANT_String
8 45.3 1.0.2 CONSTANT_Fieldref
9 45.3 1.0.2 CONSTANT_Methodref
10 45.3 1.0.2 CONSTANT_InterfaceMethodref
11 45.3 1.0.2 CONSTANT_NameAndType
12 45.3 1.0.2 CONSTANT_MethodHandle
15 51.0 7 CONSTANT_MethodType
16 51.0 7 CONSTANT_Dynamic
17 55.0 11 CONSTANT_InvokeDynamic
18 51.0 7 CONSTANT_Module
19 53.0 9 CONSTANT_Package
20 53.0 9 表中的某些条目
constant_pool
是可加载的, 因为它们表示可以在运行时压入堆栈以实现进一步计算的实体。在class
版本号为v的文件中,constant_pool
如果表中的条目具有首先被认为可在文件格式v或更早版本中加载的标记,则该表中的条目是可加载的class
。 表4.4-C列出了每个标签,class
其中包含可被加载的文件格式的第一个版本。还显示了Java SE平台的版本,该版本引入了该版本的class
文件格式。在除了之外的每种情况下
CONSTANT_Class
,首先认为标签可以在class
首先定义标签的相同版本的文件格式中加载。表4.4-C。可加载的常量池标记
常数种类 标签 class
文件格式Java SE CONSTANT_Integer
3 45.3 1.0.2 CONSTANT_Float
4 45.3 1.0.2 CONSTANT_Long
五 45.3 1.0.2 CONSTANT_Double
6 45.3 1.0.2 CONSTANT_Class
7 49.0 5 CONSTANT_String
8 45.3 1.0.2 CONSTANT_MethodHandle
15 51.0 7 CONSTANT_MethodType
16 51.0 7 CONSTANT_Dynamic
17 55.0 11 查看全部 -
JDK12 其他特性
查看全部 -
属性总结
应用场景
查看全部 -
GC 模式
查看全部 -
堆内存结构
查看全部 -
G1垃圾收集器的增强
查看全部 -
共享类数据缓存
查看全部 -
微基准测试
查看全部 -
List新增的API
查看全部
举报