首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用MethodHandles在编译时未知的类上调用方法(无反射)

MethodHandles是Java SE 7中引入的一种新的API,它提供了一种在编译时未知的类上调用方法的方式,而无需使用传统的反射机制。

MethodHandles可以被看作是对Java中方法的一种引用,它可以在运行时动态地绑定到方法,并且可以在不同的上下文中执行。相比于传统的反射机制,MethodHandles具有更高的性能和更好的类型检查。

使用MethodHandles进行方法调用的过程如下:

  1. 获取MethodHandles.Lookup对象:MethodHandles.Lookup是MethodHandles的工厂类,可以通过它获取MethodHandles对象。
  2. 获取MethodHandle对象:MethodHandle是对方法的引用,可以通过MethodHandles.Lookup的一些方法获取MethodHandle对象,例如findVirtual()、findStatic()等。
  3. 调用方法:通过MethodHandle的invoke()方法调用方法,传入相应的参数。

MethodHandles的优势:

  1. 性能高效:相比于传统的反射机制,MethodHandles的性能更高,因为它直接操作字节码,避免了反射中的一些开销。
  2. 类型检查严格:MethodHandles在编译时进行类型检查,可以在编译时发现一些错误,而不是在运行时抛出异常。
  3. 支持方法调用链:MethodHandles可以将多个方法调用链接在一起,形成一个方法调用链,提高代码的可读性和可维护性。

MethodHandles的应用场景:

  1. 框架开发:MethodHandles可以用于框架开发中,动态地调用用户提供的方法,实现插件式的扩展。
  2. AOP编程:MethodHandles可以用于实现AOP编程,通过MethodHandles可以在不修改源代码的情况下,对方法进行增强。
  3. 动态代理:MethodHandles可以用于实现动态代理,通过MethodHandles可以动态地生成代理类,并在代理类中调用目标方法。

腾讯云相关产品和产品介绍链接地址:

腾讯云提供了丰富的云计算产品和服务,以下是一些与MethodHandles相关的产品和服务:

  1. 云函数(Serverless):腾讯云云函数是一种事件驱动的无服务器计算服务,可以使用MethodHandles在函数中动态调用方法。详细信息请参考:https://cloud.tencent.com/product/scf
  2. 弹性MapReduce(EMR):腾讯云弹性MapReduce是一种大数据处理服务,可以使用MethodHandles在MapReduce任务中动态调用方法。详细信息请参考:https://cloud.tencent.com/product/emr
  3. 人工智能机器学习平台(AI Lab):腾讯云AI Lab提供了丰富的人工智能和机器学习服务,可以使用MethodHandles在机器学习模型中动态调用方法。详细信息请参考:https://cloud.tencent.com/product/ailab

请注意,以上链接仅供参考,具体的产品和服务选择应根据实际需求进行评估和选择。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++中反射调用.NET(一) 反射调用第一个.NET方法

为什么要在C++中调用.NET 一般情况下,我们常常会在.NET程序中调用C/C++程序,使用P/Invoke方式进行调用,在编写代码代码时候,首先要导入DLL文件,然后根据C/C++头文件编写特殊...注意,本文说C++反射调用,不是对C++自身进行封装反射功能,而是C++/CLI代码中反射调用.NET代码,原理上跟你.NET应用中反射调用另外一个.NET程序集一个道理。...我们先在NetLib项目写一个简单.NET ,这个方法内部没有复杂业务逻辑代码,仅仅用来供反射调用测试: namespace NetLib { public class User...C++中,成员用 -> 符号调用,命名空间或者静态成员,用::调用,例如上面的构造函数中代码: Assembly^ ass = Assembly::LoadFrom(this->assemblyFile...C++/CLI中使用反射 反射调用第一个.NET方法 下面的方法,将会反射调用 User一个最简单方法 : public int GetUserID(string IdString){} 该方法只有一个一个参数和一个简单返回值

3.2K100

使用 Java 中反射机制调用私有方法原理详解

文章目录 前言 一、私有方法本类中直接调用 1、本类中实例化,调用私有方法 2、尝试在其他直接调用私有方法(错误示范) 二、使用反射机制实例化强制调用私有方法 1、使用加载器加载被调用 2...2、尝试在其他直接调用私有方法(错误示范) 如果我们直接在其他中实例化Demo,来直接调用demo()方法,就会发现 IDE 直接产生编译错误,很明显我们直接在另一个调用私有方法是行不通,...二、使用反射机制实例化强制调用私有方法 1、使用加载器加载被调用 Class<?...说明:当值为true,指反射对象使用时应该取消 Java 语言访问检查,值为false则只是反射对象应该试试 Java 语言访问检查。当值设置为true,不接受检查,可以提高反射运行速度。...原则要求不准定义私有的方法,我们使用 method.invoke(Object obj,Object args[]); 强制调用对象调用私有方法违反了我们 Java 中面向对象特性。 ?

3.7K31

关于使用MethodHandle子类中调用祖父重写方法探究

关于使用MethodHandle子类中调用祖父重写方法探究 注:这个例子原本出现在周志明先生《深入理解Java虚拟机》--虚拟机字节码执行引擎章节,介于有读者朋友有疑问,这里基于Java代码层面解释一下...这里直接看Sonthinking方法(关于为何这样实现,《深入理解Java虚拟机》读书笔记(七)--虚拟机字节码执行引擎(下)中也解释了)。...普通方法调用中,这个this参数是虚拟机自动处理,表示是当前实例对象,我们方法中可以直接使用。...基于这个事实,我们这时可以直接在GrandFatherthinking方法调用Son独有的方法使用反射或者直接类型强制转换为Son就行了。...我们也可以使用findVirtual找到该方法,不过就需要一个GrandFather实例对象(当然也就不用使用反射了): static class Son extends Father { void

9.4K30

MethodHandle结合LambdaMetafactory-使用方法及性能测试

# 背景 进行实例动态推断和构建,我们会经常使用反射这一技巧,然而在某些场景中反射效率显得有些力不从心。从JDK7开始,MethodHandle被推出,用于解决反射效率问题。...提示 OptaPlanner是一个开源轻量级、可嵌入约束满足引擎,可求解规划问题,100%由Java编写,可以在任何JVM运行,也可以Maven中央存储库中使用、支持多种平台下载。...本文中,MethodHandle主要解决如下2个问题 外访问private变量并动态赋值 动态根据class带入参创建实例 虽然反射实现起来很简单,但由于这两种场景工具使用高频,所以出于性能考量采用了...MethodHandle是不会比直接反射更快使用时应该注意这一情况,静态化之后,反射和MethodHandle都得到了显著效率提升,此时MethodHandle效率更高。...还会编写大量LambdaMetafactory使用代码。本质是因为异常实例化消耗绝大多数在于堆栈收集,仅仅是创建实例场景比较有限,优势也不会太明显。

1.6K40

更高效反射调用方式被我找到了!

背景 使用Java进行开发,我们会不可避免使用到大量反射操作,比如Spring Boot会在接收到HTTP请求,利用反射Controller调用接口中对应方法,或是Jackson框架使用反射来解析...有兴趣小伙伴可以去了解一下 Test中,具有一个简单int类型变量,我们分别测试直接调用构造方法,赋值然后取值,以及使用Constructor和Method进行普通反射调用之间性能对比,...MethodHandle与使用普通反射之间性能差距,就和普通反射与直接调用之间差距一样大,事实JDK18以后,根据# JEP 416: Reimplement Core Reflection with...鉴于我们之前这些测试结果,如果想要进一步提升反射性能,只能考虑使用生成方式,在编译期创建出MethodHandle静态变量,让JVM帮我们去自动内联,当然,生成方式一定可以拥有非常不错性能...小结 本文介绍了一种Java中反射调用方式,即使用类似于Lambda表达式生成方式进行反射,可以将一些简单方法,例如get和set方法,直接转化为相应Lambda表达式来调用,虽然可以做到和直接调用一致性能

20110

这代码写跟狗屎一样!怎么优化?19招搞定它

1.使用局部变量可避免堆上分配 咱们都知道,JVM中创建对象,基本都是堆中,另外由于堆资源是多线程共享,是垃圾回收器工作主要区域,过多对象会造成JVM垃圾回收压力增大。 怎么办呢?...其实,我们完全可以通过局部变量方式,将变量分配。这种方式变量会随着方法执行完毕而销毁,能够减轻 JVM垃圾回收压力。... Linux ,通过加入JVM配置 -Djava.security.egd=file:/dev/./urandom,使用 urandom 随机生成器,进行随机数获取,速度会更快。...现实中有很多对反射优化方法,比如把反射执行过程(比如 Method)缓存起来,使用复用来加快反射速度。...下面是一个使用 MethodHandle 编写代码实现。它可以完成一些动态语言特性,通过方法名称和传入对象主体,进行不同调用,而 Bike 和 Man ,可以是没有任何关系

21510

Java Record 一些思考 - 默认方法使用以及基于预编译生成相关字节码底层实现

这个包主要目的是之前单纯依靠符号引用来确定调用目标方法这种方式以外,提供一种新动态确定目标方法机制,称为MethodHandle。...通过 MethodHandle 可以动态获取想调用方法进行调用,和 Java Reflection 反射类似,但是为了追求性能效率,需要用 MethodHandle,主要原因是: Reflection...仅仅是 Java 语言补充针对反射实现,并没有考虑效率问题,尤其是 JIT 基本无法针对这种反射调用进行有效优化。...MethodHandle 更是像是对于字节码方法指令调用模拟,适当使用的话 JIT 也能对于它进行优化,例如将 MethodHandle 相关方法引用声明为 static final : private...,实际 toString() 调用是 java.lang.runtime.ObjectMethods bootstap() 方法

32710

Record 默认方法使用以及基于预编译生成相关字节码底层实现

值类型最终版设计,可以正式在生产使用 Java 值类型相关 API 也就是 Record 这个了。...这个包主要目的是之前单纯依靠符号引用来确定调用目标方法这种方式以外,提供一种新动态确定目标方法机制,称为MethodHandle。...通过 MethodHandle 可以动态获取想调用方法进行调用,和 Java Reflection 反射类似,但是为了追求性能效率,需要用 MethodHandle,主要原因是: Reflection...仅仅是 Java 语言补充针对反射实现,并没有考虑效率问题,尤其是 JIT 基本无法针对这种反射调用进行有效优化。...,实际 toString() 调用是 java.lang.runtime.ObjectMethods bootstap() 方法

2.4K40

Java 虚拟机:JVM是怎么实现invokedynamic?(

方法句柄类型(MethodType)是由所指向方法参数类型以及返回类型组成。它是用来确认方法句柄是否适配唯一关键。当使用方法句柄,我们其实并不关心方法句柄所指向方法名或者方法名。...方法句柄创建是通过 MethodHandles.Lookup 来完成。它提供了多个 API,既可以使用反射 API 中 Method 来查找,也可以根据方法名以及方法句柄类型来查找。...但它与反射 API 不同,其权限检查是句柄创建阶段完成实际调用过程中,Java 虚拟机并不会检查方法句柄权限。如果该句柄被多次调用的话,那么与反射调用相比,它将省下重复权限检查开销。...碰到被它注解方法调用时,Java 编译器会根据所传入参数声明类型来生成方法描述符,而不是采用目标方法所声明描述符。...刚才例子中,当传入参数是 String ,对应方法描述符包含 String ;而当我们转化为 Object ,对应方法描述符则包含 Object

95530

理解 JDK 中 MethodHandle

,动态调用想要方法。...注意到MethodHandle比Method多了一个invokeExact方法,它与invoke区别是方法参数、返回值匹配非常严格,调用时如果有数值参数隐式转换(如short转int/子类转父)、装箱拆箱...简单来说就是调用标记了PolymorphicSignature方法,不管源码传什么参数都是可以编译通过编译器其实不按源码中描述方法签名生成字节码,而是参考实际传入参数形式类型(或者称为变量类型更合适...MethodHandle文档描述中还有一点值得关注:MethodHandle访问性检查只创建检查一次,而Method则是每次调用都检查。...也就是说,使用MethodHadle更像平时写Java代码,只有public成员是可以访问,protected、private成员只能在内部代码才能用MethodHandles工厂方法访问,外部是无法生成

5.1K00

JAVA代码优化十九式!

1.使用局部变量可避免堆上分配 由于堆资源是多线程共享,是垃圾回收器工作主要区域,过多对象会造成 GC 压力。可以通过局部变量方式,将变量分配。... Linux ,通过加入 JVM 配置 「-Djava.security.egd=file:/dev/./urandom」 ,使用 urandom 随机生成器,进行随机数获取,速度会更快。...现实中有很多对反射优化方法,比如把反射执行过程(比如 Method)缓存起来,使用复用来加快反射速度。...下面是一个使用 MethodHandle 编写代码实现。它可以完成一些动态语言特性,通过方法名称和传入对象主体,进行不同调用,而 Bike 和 Man ,可以是没有任何关系。...({content}); Pattern 编译非常耗时,它 Matcher 方法是线程安全,每次调用方法这个方法都会生成一个新 Matcher 对象。

21010

Record 默认方法使用以及底层实现

值类型最终版设计,可以正式在生产使用 Java 值类型相关 API 也就是 Record 这个了。...这个包主要目的是之前单纯依靠符号引用来确定调用目标方法这种方式以外,提供一种新动态确定目标方法机制,称为MethodHandle。...通过 MethodHandle 可以动态获取想调用方法进行调用,和 Java Reflection 反射类似,但是为了追求性能效率,需要用 MethodHandle,主要原因是: Reflection...仅仅是 Java 语言补充针对反射实现,并没有考虑效率问题,尤其是 JIT 基本无法针对这种反射调用进行有效优化。...,实际 toString() 调用是 java.lang.runtime.ObjectMethods bootstap() 方法

1.9K11

装逼利器,看完这篇,让只懂反射同学仰视你

反射(Reflect)作为Java最重要一种机制,相信大家一定都很熟悉了,今天指北君要介绍另一种和反射机制类似的方法调用机制——MethodHandle。...核心代码解读 上面我们展示了一个最进本MethodHandle方式方法调用,下面我们将对其中用到主要进行介绍。...这些主要包含MethodType,MethodHandle,MethodHandles及Lookup。...调用方法 MethodHandles, Lookup MethodHandles不是MethodHandle实现,他提供工具用于帮助获取MethodHandle,我们主要使用到lookup(),publicLookup...最后,通过LookupfindXXX获取到MethodHandle,详细说明见下表: ? 查找方法 小结 关于MethodHandle基本使用就基本讲完,这里指北君附上一张图便大家理解: ?

44320

Java8特性详解 lambda表达式(三):原理篇

每个匿名内部类都会在编译创建一个对应class,并且是有文件,因此在运行时不可避免会有加载、验证、准备、解析、初始化加载过程。...dynamic typing: 变量类型在编译不能确定,只能在运行时才能确定、检查。 例如如下动态语言例子,a和b类型都是未知,因此a.append(b)这个方法是什么也是未知。...要实现动态分派,既然不能在编译决定,那么我们把这个决策推迟到运行时再决定,由用户自定义代码告诉给JVM要执行什么方法。...最开始处于未链接(unlinked)状态,这时这个指令并不知道要调用目标方法是什么。...$Lookup类型caller参数,这个对象能够通过类似反射方式拿到执行invokedynamic指令这个环境下能够调动到方法,比如其他private方法调用不到

62020

基础篇:深入解析JAVA注解机制

和Javadoc不同,java注解可以通过反射获取标注内容 在编译器生成.class文件,注解可以被嵌入字节码中,而jvm也可以保留注解内容,在运行时获取注解标注内容信息 java提供注解可以分成两...如果发现其父,或者是引用接口中并没有该方法,会报编译错误 @Deprecated 标记过时方法。...(和关键字@interface配合使用注解) 元注解名称 功能描述 @Retention 标识这个注释解怎么保存,是只代码中,还是编入文件中,或者是在运行时可以通过反射访问 @Documented...标识这些注解是否包含在用户文档中 @Target 标识这个注解作用范围 @Inherited 标识注解可被继承获取 @Repeatable 标识某注解可以同一个声明使用多次 Annotation...代码里定义注解,会被jvm利用反射技术生成一个代理,然后和被注释代码(方法,属性等)关联起来 五种元注解详解 @Retention:指定注解信息保留阶段,有如下三种枚举选择。

62010

揭密 Java方法调用底层原理

版本低于编译 JDK 版本(52 是 Java 8 主版本号)。...回想加载机制, class 文件被加载到方法区以后,就完成了从符号引用到具体地址转换过程。 我们可以看一下编译 main 方法字节码,尤其需要注意是对于接口方法调用。...,大多数普通方法调用使用是 invokevirtual指令,它其实和invokeinterface是一,都属于虚方法调用。...由于方法调用非常频繁,JVM 对动态调用代码进行了比较多优化,比如使用方法表来加快对具体方法寻址,以及使用更快缓冲区来直接寻址( 内联缓存)。...和反射类似,它用于一些动态调用场景,但它和反射有着本质不同,效率也比反射要高得多。

1.3K20

报告,书里有个BUG!

整个第八章主要分析了虚拟机执行代码,如何找到正确方法、如何执行方法字节码,以及执行代码涉及内存结构。...但是可惜是 super 调用是父 thinking 方法,而当前 son 是 Father 。...这个思路是可以,但是属于作弊行为。 题目是要求字节码之上 Java 层面解决。 有的同学还能想到反射。 诶,想到反射同学很不错,可以给自己鼓个掌。...比如在书中例中, Son 调用 MethodHandles.lookup,Son 是调用者,因为调用者是敏感,所以只能访问到 Father thinking。...: 结合着这个看,基本就能看懂了: 不得不说,反射真的是太“流氓”了。

34320

深入探究JVM之方法调用及Lambda表达式实现原理

Java中有非虚方法和虚方法,前者是指在解析阶段可以确定唯一调用版本,如静态方法、构造器方法、父方法(特指在子类中使用super调用,而不是客户端使用对象引用调用)、私有方法(上述几种方法使用...invokestatic和invokespecial指令调用)以及被final修饰方法使用invokevirtual调用),这些方法加载阶段就会把方法符号引用解析为直接引用;除此之外都是虚方法...这里全都是调用参数为Human类型方法,原因就是main方法中定义变量类型都是Human,这个就属于静态类型,而等于后面的对象则属于实际类型,实际类型只能在运行期间获取到,因此编译器在编译阶段只能根据静态类型选取到对应方法...这里面第一步就是在运行期间找到接收者实际类型,真正调用方法就是根据这个类型进行调用,所以会产生不同结果。...另外我们可以发现MethodHandle功能和使用上都和反射差不多,但是使用更加简单,也更轻量级,对应性能也比反射要高。

70030

你知道 Java 中隐藏吗?

什么是隐藏 隐藏,是一种不能被其他直接使用。引入隐藏主要目的是给框架来使用,使得框架可以在运行时生成,并通过反射间接使用它们。...return "https://www.didispace.com";     } } 第二步:编译一下,或得编译class文件。...第三步:通过反射加载上面生成,并调用隐藏hello函数,代码如下: /**  * 程序猿DD  * <a href="https://www.didispace.com/java-features...第二行:输出了这个隐藏<em>类</em>下<em>的</em><em>方法</em>名称 第三行:<em>调用</em>隐藏<em>类</em>下<em>的</em>hello<em>方法</em>获得<em>的</em>返回内容 是不是还挺简单?...另外,如果你最近想跳槽的话,年前我花了2周<em>时</em>间收集了一波大厂面经,节后准备跳槽<em>的</em>可以点击这里领取!

62810

当我们在谈论 memory order 时候,我们在谈论什么

acquire本质是read-acquire,它只能应用在从RAM中read数据这种操作,它确保了所有acquire之后语句不会被调整到它之前执行,如下图所示。...VarHandle设计目的是为了替代java.util.concurrent.atomic以及sun.misc.Unsafe这两个一些方法,标准中指出这两个一些方法存在性能和可移植性问题,...VarHandle intArrayHandle = MethodHandles.arrayElementVarHandle(int[].class); 获取到VarHandle实例后,如何用这个去修改域呢...用VarHandle反射获取MethodHandle方法如下: Foo f = ......,但是考虑到特定cpu或者编译优化指令时会有重排序情况,了解这些知识有助于调试一些疑难杂症。

4K21
领券