当前位置: 首页 > news >正文

论文网站建设与运营小程序开发平台

论文网站建设与运营,小程序开发平台,wordpress模板修改,网站制作思路在Java中,方法调用会被编译为invokeStatic,invokeSpecial,invokVirtual以及invokeInterface四种指令。这些指令与包含目标方法类名、方法名以及方法描述符的符号引用捆绑,在实际运行之前,JVM根据这个符号引用链接到具体…

在Java中,方法调用会被编译为invokeStaticinvokeSpecialinvokVirtual以及invokeInterface四种指令。这些指令与包含目标方法类名、方法名以及方法描述符的符号引用捆绑,在实际运行之前,JVM根据这个符号引用链接到具体目标方法。

JDK7 引入新的指令invodeDynamic该指令的调用机制抽象出调用点这一个概念,并允许应用程序将调用点链接至任意符合条件的方法上。同时JDK7 还配套引入了更加低层、更加抽象的方法抽象:方法句柄(invokedynamic 底层机制的基石:方法句柄。)。

一、方法句柄

1.方法句柄概念

强类型,能够被直接执行的引用。
方法句柄的类型是由所指向方法的参数以及返回类型组成的。它是用来确认方法句柄是否适配的唯一关键。

  • 方法句柄的获取
class Foo {private static void bar(Object o) {..}public static Lookup lookup() {return MethodHandles.lookup();}
}// 获取方法句柄的不同方式
MethodHandles.Lookup l = Foo.lookup(); // 具备 Foo 类的访问权限
Method m = Foo.class.getDeclaredMethod("bar", Object.class);
MethodHandle mh0 = l.unreflect(m);MethodType t = MethodType.methodType(void.class, Object.class);
MethodHandle mh1 = l.findStatic(Foo.class, "bar", t);
  • 方法句柄的权限
    与反射 API 不同,其权限检查是在句柄的创建阶段完成的。在实际调用过程中,JVM不会检查方法句柄的权限。

方法句柄的访问权限不取决于方法句柄的创建位置,而是取决于 Lookup对象的创建位置

举个例子,对于一个私有字段,如果 Lookup 对象是在私有字段所在类中获取的,则这个Lookup对象便拥有对该私有字段的访问权限,
即使是在所在类的外边,也能够通过该 Lookup 对象创建该私有字段的getter 或 setter

2.方法句柄的操作

  1. 方法句柄的调用有两种模式:
  • invokeExact(需要严苛匹配参数类型)
    一个方法句柄将接收一个 Object 类型的参数,如果你直接传入String作为实际参数,则方法句柄的调用会在运行时抛出方法类型不匹配的异常
  • invoke(自动适配参数类型)
    invoke 会调用 MethodHandle.asType方法,生成一个适配器方法句柄,对传入的参数进行适配,再调用原方法句柄;调用原方法句柄的返回值同样会先进行适配,然后再返回给调用者。
  1. 方法句柄支持增删改参数的操作
  • 改操作:MethodHandle.asType 方法
  • 删操作:将传入的部分参数就地抛弃,再调用另一个方法句柄。它对应的API 是 MethodHandles.dropArguments方法
  • 增操作:它会往传入的参数中插入额外的参数,再调用另一个方法句柄,它对应的 API 是 MethodHandle.bindTo 方法;Java 8 中捕获类型的 Lambda 表达式便是用这种操作来实现的
增操作还可以用来实现方法的柯里化。举个例子,有一个指向 f(x, y) 的方法句柄,我们可以通过将 x 绑定为 4,生成另一个方法句柄 g(y) = f(4, y)。
在执行过程中,每当调用 g(y) 的方法句柄,它会在参数列表最前面插入一个 4,再调用指向 f(x, y) 的方法句柄。

柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

3.方法句柄的实现

方法句柄的调用和反射调用一样,都是间接调用。因此,它也会面临无法内联的问题。不过,与反射调用不同的是,方法句柄的内联瓶颈在于即时编译器能否将该方法句柄识别为常量。

二、invokeDynamic指令

1.调用点介绍

invokedynamic 是 Java 7 引入的一条新指令,用以支持动态语言的方法调用。具体来说,它将调用点(CallSite)抽象成一个 Java 类,并且将原本由 Java 虚拟机控制的方法调用以及方法链接暴露给了应用程序。在运行过程中,每一条 invokedynamic 指令将捆绑一个调用点,并且会调用该调用点所链接的方法句柄。
在第一次执行 invokedynamic 指令时,Java 虚拟机会调用该指令所对应的启动方法(BootStrap Method),来生成前面提到的调用点,并且将之绑定至该 invokedynamic 指令中。在之后的运行过程中,Java 虚拟机则会直接调用绑定的调用点所链接的方法句柄。

invokedynamic 的目的,就是将调用点与目标方法的链接交由应用程序来做,并且依赖于应用程序对目标方法进行验证。所以,如果应用程序将赛跑方法链接至兔子的睡觉方法,那也只能怪应用程序自己了。

2.Java8 中lambda表达式

Java8中的lambda是借助于invokeDynamic来实现的。

具体来说,Java 编译器利用 invokedynamic 指令来生成实现了函数式接口的适配器。

函数式接口指的是仅包括一个非 default 接口方法的接口,一般通过 @FunctionalInterface 注解,不过就算是没有使用该注解,Java 编译器也会将符合条件的接口辨认为函数式接口

int x = ..
IntStream.of(1, 2, 3).map(i -> i * 2).map(i -> i * x);上面这段代码会对 IntStream 中的元素进行两次映射。映射方法 map 所接收的参数是 IntUnaryOperator(这是一个函数式接口)。
也就是说,在运行过程中我们需要将 i->i*2 和 i -> i*x 这两个lambda表达式转化成IntUnaryOperator实例,
这个转换过程就是通过invokeDynamic实现的;在编译过程中,Java 编译器会对 Lambda 表达式进行解语法糖(desugar),
生成一个方法来保存 Lambda 表达式的内容。该方法的参数列表不仅包含原本 Lambda 表达式的参数,还包含它所捕获的变量。
(注:方法引用,如 Horse::race,则不会生成生成额外的方法。)在上面那个例子中,第一个 Lambda 表达式没有捕获其他变量,而第二个 Lambda 表达式(也就是 i->i*x)则会捕获局部变量 x。
这两个 Lambda 表达式对应的方法如下所示。可以看到,所捕获的变量同样也会作为参数传入生成的方法之中。
http://www.tj-hxxt.cn/news/93874.html

相关文章:

  • 共享充电宝开发影响seo排名的因素
  • 做网站的公司 成都网站建设有哪些公司
  • 研学网站平台建设方案深圳百度推广联系方式
  • 权威的手机网站制作百度指数查询工具
  • 做网站余姚seo数据分析哪些方面
  • 饲料网站建设 中企动力推广接单平台
  • 南京哪家公司做企业网站 做得比较好朋友圈营销广告
  • wordpress账号密码数据库百色seo快速排名
  • 搭建什么网站赚钱应用宝aso优化
  • 新手做网站应该注意什么外贸营销网站
  • 什么是可信网站认证北京百度推广电话
  • 手机网站建设 小程序短视频营销案例
  • 单页网站seo杭州seo网站优化
  • 怎么知道自己的网站被k市场营销一般在哪上班
  • 扁平化设计 科技感网站素材发布软文的平台
  • 营销型网站建设宣传语seo推广软件
  • 无锡网站制作价格seo工资待遇怎么样
  • 做微信封面模板下载网站seo技术是什么
  • 企业自助建站网seogw
  • 山西手机版建站系统信息国内ip地址 免费
  • dw网页代码模板徐州seo代理计费
  • 喜茶vi设计案例分析ppt深圳排名seo公司
  • 温州市建设工程管理网站子域名在线查询
  • 在家给别人做网站合法吗seo整合营销
  • 做网站销售电销好做吗软件推广的渠道是哪里找的
  • 东城住房和城乡建设委员会网站上海百度推广开户
  • 代备案网站大概需要多少钱
  • 做专业的精品套图网站最新国际消息
  • 徐州个人建站模板app开发公司推荐
  • 做视频直播网站需要办理什么资质seo 知乎