小编典典

您可以使用MethodHandle。其Javadoc写道:

使用Lookup API中的工厂方法,可以将Core Reflection

API对象表示的任何类成员转换为行为等效的方法句柄。例如,可以使用Lookup.unreflect将反射方法转换为方法句柄。生成的方法句柄通常提供对底层类成员的更直接和有效的访问。

虽然这将减少开销,但如果使用常规(非反射)字节代码指令进行调用,则方法句柄仍会阻止JVM可以采用某些优化(此类方法内联)。这种优化是否有益取决于您使用该方法的方式(如果该代码路径始终调用同一方法,则内联可以提供帮助(如果每次都是不同的方法,则可能不会)。

以下微基准可以使您大致了解反射,方法句柄和直接调用的相对性能:

package tools.bench;

import java.lang.invoke.MethodHandle;

import java.lang.invoke.MethodHandles;

import java.lang.reflect.Method;

import java.math.BigDecimal;

public abstract class Bench {

final String name;

public Bench(String name) {

this.name = name;

}

abstract int run(int iterations) throws Throwable;

private BigDecimal time() {

try {

int nextI = 1;

int i;

long duration;

do {

i = nextI;

long start = System.nanoTime();

run(i);

duration = System.nanoTime() - start;

nextI = (i << 1) | 1;

} while (duration < 100000000 && nextI > 0);

return new BigDecimal((duration) * 1000 / i).movePointLeft(3);

} catch (Throwable e) {

throw new RuntimeException(e);

}

}

@Override

public String toString() {

return name + "\t" + time() + " ns";

}

static class C {

public Integer foo() {

return 1;

}

}

static final MethodHandle sfmh;

static {

try {

Method m = C.class.getMethod("foo");

sfmh = MethodHandles.lookup().unreflect(m);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

public static void main(String[] args) throws Exception {

final C invocationTarget = new C();

final Method m = C.class.getMethod("foo");

final Method am = C.class.getMethod("foo");

am.setAccessible(true);

final MethodHandle mh = sfmh;

Bench[] marks = {

new Bench("reflective invocation (without setAccessible)") {

@Override int run(int iterations) throws Throwable {

int x = 0;

for (int i = 0; i < iterations; i++) {

x += (Integer) m.invoke(invocationTarget);

}

return x;

}

},

new Bench("reflective invocation (with setAccessible)") {

@Override int run(int iterations) throws Throwable {

int x = 0;

for (int i = 0; i < iterations; i++) {

x += (Integer) am.invoke(invocationTarget);

}

return x;

}

},

new Bench("methodhandle invocation") {

@Override int run(int iterations) throws Throwable {

int x = 0;

for (int i = 0; i < iterations; i++) {

x += (Integer) mh.invokeExact(invocationTarget);

}

return x;

}

},

new Bench("static final methodhandle invocation") {

@Override int run(int iterations) throws Throwable {

int x = 0;

for (int i = 0; i < iterations; i++) {

x += (Integer) sfmh.invokeExact(invocationTarget);

}

return x;

}

},

new Bench("direct invocation") {

@Override int run(int iterations) throws Throwable {

int x = 0;

for (int i = 0; i < iterations; i++) {

x += invocationTarget.foo();

}

return x;

}

},

};

for (Bench bm : marks) {

System.out.println(bm);

}

}

}

在我有些过时的笔记本上

java version "1.7.0_02"

Java(TM) SE Runtime Environment (build 1.7.0_02-b13)

Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)

打印:

reflective invocation (without setAccessible) 568.506 ns

reflective invocation (with setAccessible) 42.377 ns

methodhandle invocation 27.461 ns

static final methodhandle invocation 9.402 ns

direct invocation 9.363 ns

更新:正如Irreputable所指出的那样,服务器VM具有一些不同的性能特征,因此

,仅当您可以将MethodHandle放在静态final字段中时 ,在 服务器VM中使用MethodHandle才有帮助

,在这种情况下,VM可以内联调用:

reflective invocation (without setAccessible) 9.736 ns

reflective invocation (with setAccessible) 7.113 ns

methodhandle invocation 26.319 ns

static final methodhandle invocation 0.045 ns

direct invocation 0.044 ns

我建议您衡量您的特定用例。

2020-09-18

java为何重复调用方法_通过反射调用Java中的getter:重复调用它的最快方法是什么(在性能和可伸缩性方面)?...相关推荐

  1. java 格式化日期到毫秒_关于日期:Java – SimpleDateFormat格式化程序,以毫秒为单位返回纪元时间...

    本问题已经有最佳答案,请猛点这里访问. 我是Java和编码的新手 - 我有一些代码以下列格式yyyy.MM.dd HH:mm:ss:ms返回时间戳,如下所示: SimpleDateFormat for ...

  2. python如何创建一个列表_在python中创建列表的最佳和/或最快方法

    在python中,据我所知,至少有3到4种方法来创建和初始化给定大小的列表: 简单循环append: my_list =[]fori inrange(50):my_list.append(0) 简单循 ...

  3. 在python中创建列表的最佳和/或最快方法

    在python中,据我所知,至少有3到4种方法来创建和初始化给定大小的列表: 简单循环append: my_list = [] for i in range(50):my_list.append(0) ...

  4. java 找出调用的方法_如何找到用Java调用给定方法的所有方法?

    小编典典 为了分析字节码,我建议使用ASM.给定要分析的类列表,可以使访问者找到您感兴趣的方法调用.下面是一个分析jar文件中类的实现. 请注意,ASM使用带有'/'而不是'.的internalNam ...

  5. java子类调用抽象父类方法_【坑】Spring中抽象父类属性注入,子类调用父类方法使用父类注入属性...

    运行环境 idea 2017.1.1 spring 3.2.9.RELEASE 需求背景 需要实现一个功能,该功能有2个场景A.B,大同小异 抽象一个抽象基类Base,实现了基本相同的方法BaseMe ...

  6. java代码安全检测机制_全面解析:java中的反射机制,内含代码验证解析

    什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功 ...

  7. java list sublist方法_(转)Java 中 List.subList() 方法的使用陷阱

    原文:http://blog.csdn.net/cleverGump/article/details/51105235 前言 本文原先发表在我的 iteye博客: http://clevergump. ...

  8. main方法_你知道为什么Java的main方法必须是public static void?

    来源:http://suo.im/6v9d64 Main 方法是我们学习 Java 编程语言时知道的第一个方法,你是否曾经想过为什么 main 方法是 public.static.void 的.当然, ...

  9. java clone方法_干货满满:Java中创建对象的五种方式详解

    通常来说,对象具有状态和行为,变量用来表明对象的状态,方法表明对象所具有的行为. 作为Java开发者,我们通常都是使用依赖管理系统,比如Spring去创建Java对象,但使用管理系统创建对象并不是唯一 ...

最新文章

  1. startActivityForResult和setResult详解
  2. Throwable是java.lang包中一个专门用来处理异常的类
  3. QLable显示图片 和 QLabel自适应 QLabel 文字居中
  4. python中shift_python对列进行平移变换的方法(shift)
  5. RedisDesktopManager客户端可视化工具下载安装与使用
  6. NOKIA Update for Windows Phone
  7. word2003如何设置护眼模式_ERP系统上线,如何设置采购收货的模式,提升企业的采购效率...
  8. hdu 2196 computer
  9. python字符串转浮点数_Python | 打印不同的值(整数,浮点数,字符串,布尔值)...
  10. 信息学奥赛一本通 1182:合影效果 | OpenJudge NOI 1.10 07:合影效果
  11. 《Reids 设计与实现》第三章 跳跃表
  12. 分表扩展全局序列实际操作_高可用_单表存储千万级_海量存储_分表扩展---MyCat分布式数据库集群架构工作笔记0026
  13. 苹果发布会不够酷?库克又送来了 iOS 12.2!
  14. 嵌入式学习流程(参考一)
  15. java修饰符super_Java 继承 方法重写 super关键字 访问权限修饰符
  16. .tar.bz2 解压出错问题解决方案
  17. VGA显示原理、时序标准及相关参数
  18. SAEJ1757-1-2015(一)
  19. 网站内容采集工具介绍
  20. 微信小程序新版canvas绘制图片方法

热门文章

  1. dj打碟怎么学_学DJ打碟 - Rane声卡连接
  2. 【51单片机快速入门指南】4.4:I2C 读取HMC5883L / QMC5883L 磁力计
  3. 【51单片机快速入门指南】3:中断系统
  4. 非常全的VsCode快捷键
  5. 公布生成cscope.out, cscope.files, tags的脚本文件
  6. uni-app自定义tabBar;uni-app小程序自定义tabBar;uni-app小程序修改中间tabBar导航栏大小;uni-app中间导航栏凸起;uni-app修改底部导航栏
  7. 简单的封装axios 不包含状态码和提示
  8. 前端学习(3100):vue+element今日头条管理-react简介
  9. [html] html标签的属性值是否可以省略引号?为什么?
  10. 工作380-js判断是否为空