我们知道,反射是一种灵活但缓慢的方法,用于在运行时维护和修改代码的行为.
但是如果我们必须使用这样的功能,那么与用于动态修改的Reflection API相比,Java中是否有更快的编程技术?这些替代品反对反思的利弊是什么?
随着Java 7的发布MethodHandle,它允许用户像使用其底层字节码一样调用方法.特别是,MethodHandles.Lookup该类提供工厂方法来创建访问类成员的方法句柄:
Lookup对象上的工厂方法对应于方法,构造函数和字段的所有主要用例.工厂方法创建的每个方法句柄都是特定字节码行为的功能等价物.
从功能上讲,这或多或少等同于使用反射来访问这些相同的类成员,但方法句柄比反射更快.
那么,有什么理由仍然使用反射功能一样Field#get(..)/ Method.invoke(..)或这些方法是引进了更快的方法手柄的有效过时了吗?
请注意,尽管在Java 7中引入了方法句柄,但我的问题主要与Java 8有关,在Java 8中,它们被优化为可以达到与直接字段/方法调用大致相等的性能,超过了反射的能力.
我写了一个小的基准测试性能java.lang.invoke.MethodHandle,java.lang.reflect.Method和方法的直接调用.
我读到的MethodHandle.invoke()表现几乎与直接通话相同.但我的测试结果显示另一个:MethodHandle调用比反射慢大约三倍.我的问题是什么?可能这是一些JIT优化的结果?
public class Main {
public static final int COUNT = 100000000;
static TestInstance test = new TestInstance();
static void testInvokeDynamic() throws NoSuchMethodException, IllegalAccessException {
int [] ar = new int[COUNT];
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodType mt = MethodType.methodType(int.class);
MethodHandle handle = lookup.findStatic(TestInstance.class, "publicStaticMethod", mt) ;
try {
long start = System.currentTimeMillis();
for (int i=0; i<COUNT; i++) {
ar[i] = (int)handle.invokeExact();
}
long stop = System.currentTimeMillis();
System.out.println(ar);
System.out.println("InvokeDynamic time: " + …Run Code Online (Sandbox Code Playgroud) 考虑weightclass 中的一个字段Animal。我希望能够创建用于操作此字段的getter和setter功能接口对象。
class Animal {
int weight;
}
Run Code Online (Sandbox Code Playgroud)
我目前的方法类似于用于方法的方法:
public static Supplier getter(Object obj, Class<?> cls, Field f) throws Exception {
boolean isstatic = Modifier.isStatic(f.getModifiers());
MethodType sSig = MethodType.methodType(f.getType());
Class<?> dCls = Supplier.class;
MethodType dSig = MethodType.methodType(Object.class);
String dMthd = "get";
MethodType dType = isstatic? MethodType.methodType(dCls) : MethodType.methodType(dCls, cls);
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle fctry = LambdaMetafactory.metafactory(lookup, dMthd, dType, dSig, lookup.unreflectGetter(f), sSig).getTarget();
fctry = !isstatic && obj!=null? fctry.bindTo(obj) : fctry;
return (Supplier)fctry.invoke(); …Run Code Online (Sandbox Code Playgroud) 我正在观看 java jpoint 会议的视频。
我对以下来自Alexey Shipilev报告的幻灯片有疑问:
对不起,幻灯片上的非英语。实际上作者说变量集是不可能的
r1 = 1 (Y)
r2 = 0 (x)
r3 = 1 (x)
r4 = 0 (Y)
Run Code Online (Sandbox Code Playgroud)
根据视频,他暗示显然是这样。
有人可以澄清为什么根据 JMM 设置这个值是不可能的吗?
聚苯乙烯
如果我理解 Alexey 符号是正确的,它会遵守以下代码:
public class SequentialConsistency {
static volatile int x;
static volatile int y;
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
x = 1;
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
y = 1;
}
}).start();
new …Run Code Online (Sandbox Code Playgroud)