Java MethodHandles.lookup().lookupClass()与getClass()的比较

Java MethodHandles.lookup().lookupClass()与getClass()的比较,java,Java,有人能告诉我这两种语言的(细微)区别吗 第1版: protected final Logger log = Logger.getLogger(getClass()); protected final Logger log = Logger.getLogger(MethodHandles.lookup().lookupClass()); vs 第2版: protected final Logger log = Logger.getLogger(getClass()); protected f

有人能告诉我这两种语言的(细微)区别吗

第1版:

protected final Logger log = Logger.getLogger(getClass());
protected final Logger log = Logger.getLogger(MethodHandles.lookup().lookupClass());
vs

第2版:

protected final Logger log = Logger.getLogger(getClass());
protected final Logger log = Logger.getLogger(MethodHandles.lookup().lookupClass());
版本2通常比版本1快吗


我猜版本1使用反射(在运行时)来确定当前类,而版本2不需要使用反射,或者(检查是在构建时完成的)?

第一种情况中不涉及反射。映射到JVM的本机方法

您的是而不是
对象#getClass()
的替代品,用于查找方法句柄

所以微妙的区别是,它们用于完全不同的目的。

这些是完全不同的东西。
lookupClass
的文档特别说明:

说明哪个类正在执行查找。正是此类对其执行可见性和访问权限检查

所以它是执行查找的类。它不一定是调用
MethodHandles.lookup()
的类。我的意思是:

Class<?> c = MethodHandles.privateLookupIn(String.class, MethodHandles.lookup()).lookupClass();
System.out.println(c); 
通常应该是一个
静态
字段,如果是,则不能调用
getClass

一个
JMH
测试表明,对代码进行如此多的模糊处理不会带来性能提升:

@State(Scope.Benchmark)
@基准模式(模式平均时间)
@输出时间单位(时间单位纳秒)
@预热(迭代次数=5,时间=2,时间单位=timeUnit.s)
@测量(迭代次数=5,时间=2,时间单位=时间单位。秒)
公共类查找测试{
私有静态final MethodHandles.Lookup Lookup=MethodHandles.Lookup();
公共静态void main(字符串[]args)引发RunnerException{
Options opt=new OptionsBuilder().include(LookupTest.class.getSimpleName())
.verbosity(VerboseMode.EXTRA)
.build();
new Runner(opt.run();
}
@基准
@叉子(3)
公共类getClassCall(){
返回getClass();
}
@基准
@叉子(3)
公共类methodHandlesInPlaceCall(){
返回MethodHandles.lookup().lookupClass();
}
@基准
@叉子(3)
公共类methodHandleCall(){
返回LOOKUP.lookupClass();
}
}
结果:

Benchmark                            Mode  Cnt  Score   Error  Units
LookupTest.getClassCall              avgt   15  2.264 ± 0.044  ns/op
LookupTest.methodHandlesCall         avgt   15  2.262 ± 0.030  ns/op
LookupTest.methodHandlesInPlaceCall  avgt   15  4.890 ± 0.783  ns/op

好的,如果发现在接口中使用MethodHandles并没有给我运行时类,而是接口类。因此,这不是一个下降的替代品。不知道为什么有些人在定义记录器时更喜欢MethodHandles而不是getClass()。使用
MethodHandles
来定义记录器肯定不常见。您是否参考过此类代码?例如:或。但是他们没有解释为什么我应该选择一个而不是另一个(例如,在性能、查找成本等方面)。也许你可以更好地解释:)@nimo23性能方面,几乎没有区别。尤金:谢谢你的很好的解释:)顺便说一句,
通常应该是一个静态字段,如果它是
,你不能调用getClass,在我的例子中,记录器是在抽象类中定义的,所以我需要非静态版本。@nimo23我明白了,我们通过
@Slf4j