mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
fix code
This commit is contained in:
@@ -16,8 +16,11 @@ import org.dromara.hutool.core.exceptions.UtilException;
|
|||||||
import org.dromara.hutool.core.lang.Assert;
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
import org.dromara.hutool.core.lang.mutable.MutableEntry;
|
||||||
import org.dromara.hutool.core.map.WeakConcurrentMap;
|
import org.dromara.hutool.core.map.WeakConcurrentMap;
|
||||||
import org.dromara.hutool.core.reflect.*;
|
import org.dromara.hutool.core.reflect.MethodHandleUtil;
|
||||||
import org.dromara.hutool.core.reflect.*;
|
import org.dromara.hutool.core.reflect.MethodUtil;
|
||||||
|
import org.dromara.hutool.core.reflect.ModifierUtil;
|
||||||
|
import org.dromara.hutool.core.reflect.ReflectUtil;
|
||||||
|
import org.dromara.hutool.core.reflect.lookup.LookupUtil;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.invoke.*;
|
import java.lang.invoke.*;
|
||||||
@@ -103,7 +106,7 @@ public class LambdaFactory {
|
|||||||
final boolean isSerializable = Serializable.class.isAssignableFrom(functionInterfaceType);
|
final boolean isSerializable = Serializable.class.isAssignableFrom(functionInterfaceType);
|
||||||
|
|
||||||
final Method invokeMethod = abstractMethods.get(0);
|
final Method invokeMethod = abstractMethods.get(0);
|
||||||
final MethodHandles.Lookup caller = LookupFactory.lookup(executable.getDeclaringClass());
|
final MethodHandles.Lookup caller = LookupUtil.lookup(executable.getDeclaringClass());
|
||||||
final String invokeName = invokeMethod.getName();
|
final String invokeName = invokeMethod.getName();
|
||||||
final MethodType invokedType = methodType(functionInterfaceType);
|
final MethodType invokedType = methodType(functionInterfaceType);
|
||||||
final MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes());
|
final MethodType samMethodType = methodType(invokeMethod.getReturnType(), invokeMethod.getParameterTypes());
|
||||||
|
@@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
|
||||||
* Hutool is licensed under Mulan PSL v2.
|
|
||||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
||||||
* You may obtain a copy of Mulan PSL v2 at:
|
|
||||||
* http://license.coscl.org.cn/MulanPSL2
|
|
||||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
||||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
||||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
||||||
* See the Mulan PSL v2 for more details.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dromara.hutool.core.reflect;
|
|
||||||
|
|
||||||
import org.dromara.hutool.core.exceptions.UtilException;
|
|
||||||
import org.dromara.hutool.core.lang.caller.CallerUtil;
|
|
||||||
import org.dromara.hutool.core.util.JdkUtil;
|
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link MethodHandles.Lookup}工厂,用于创建{@link MethodHandles.Lookup}对象<br>
|
|
||||||
* {@link MethodHandles.Lookup}是一个方法句柄查找对象,用于在指定类中查找符合给定方法名称、方法类型的方法句柄。
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
|
||||||
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* 参考:
|
|
||||||
* <p><a href="https://blog.csdn.net/u013202238/article/details/108687086">https://blog.csdn.net/u013202238/article/details/108687086</a></p>
|
|
||||||
*
|
|
||||||
* @author looly
|
|
||||||
* @since 5.7.7
|
|
||||||
*/
|
|
||||||
public class LookupFactory {
|
|
||||||
|
|
||||||
private static final int ALLOWED_MODES = MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
|
|
||||||
| MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC;
|
|
||||||
|
|
||||||
private static Method privateLookupInMethod;
|
|
||||||
private static Constructor<MethodHandles.Lookup> jdk8LookupConstructor;
|
|
||||||
|
|
||||||
static {
|
|
||||||
if(JdkUtil.IS_JDK8){
|
|
||||||
// jdk8 这种方式其实也适用于jdk9及以上的版本,但是上面优先,可以避免 jdk9 反射警告
|
|
||||||
jdk8LookupConstructor = createJdk8LookupConstructor();
|
|
||||||
} else {
|
|
||||||
// jdk9+ 开始提供的java.lang.invoke.MethodHandles.privateLookupIn方法
|
|
||||||
privateLookupInMethod = createJdk9PrivateLookupInMethod();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
|
||||||
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
|
||||||
*
|
|
||||||
* @return {@link MethodHandles.Lookup}
|
|
||||||
*/
|
|
||||||
public static MethodHandles.Lookup lookup() {
|
|
||||||
return lookup(CallerUtil.getCaller());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
|
||||||
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
|
||||||
*
|
|
||||||
* @param callerClass 被调用的类或接口
|
|
||||||
* @return {@link MethodHandles.Lookup}
|
|
||||||
*/
|
|
||||||
public static MethodHandles.Lookup lookup(final Class<?> callerClass) {
|
|
||||||
//使用反射,因为当前jdk可能不是java9或以上版本
|
|
||||||
if (privateLookupInMethod != null) {
|
|
||||||
try {
|
|
||||||
return (MethodHandles.Lookup) privateLookupInMethod.invoke(MethodHandles.class, callerClass, MethodHandles.lookup());
|
|
||||||
} catch (final IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new UtilException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//jdk 8
|
|
||||||
try {
|
|
||||||
return jdk8LookupConstructor.newInstance(callerClass, ALLOWED_MODES);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
throw new IllegalStateException("no 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("JavaReflectionMemberAccess")
|
|
||||||
private static Method createJdk9PrivateLookupInMethod(){
|
|
||||||
try {
|
|
||||||
return MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
|
|
||||||
} catch (final NoSuchMethodException e) {
|
|
||||||
//可能是jdk9 以下版本
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"There is no 'privateLookupIn(Class, Lookup)' method in java.lang.invoke.MethodHandles.", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Constructor<MethodHandles.Lookup> createJdk8LookupConstructor(){
|
|
||||||
final Constructor<MethodHandles.Lookup> constructor;
|
|
||||||
try {
|
|
||||||
constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
|
|
||||||
} catch (final NoSuchMethodException e) {
|
|
||||||
//可能是jdk8 以下版本
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"There is no 'Lookup(Class, int)' constructor in java.lang.invoke.MethodHandles.", e);
|
|
||||||
}
|
|
||||||
constructor.setAccessible(true);
|
|
||||||
return constructor;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,6 +14,7 @@ package org.dromara.hutool.core.reflect;
|
|||||||
|
|
||||||
import org.dromara.hutool.core.exceptions.UtilException;
|
import org.dromara.hutool.core.exceptions.UtilException;
|
||||||
import org.dromara.hutool.core.lang.Assert;
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
|
import org.dromara.hutool.core.reflect.lookup.LookupUtil;
|
||||||
import org.dromara.hutool.core.text.StrUtil;
|
import org.dromara.hutool.core.text.StrUtil;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
@@ -51,9 +52,9 @@ public class MethodHandleUtil {
|
|||||||
public static MethodHandle unreflect(final Member methodOrConstructor) {
|
public static MethodHandle unreflect(final Member methodOrConstructor) {
|
||||||
try {
|
try {
|
||||||
if (methodOrConstructor instanceof Method) {
|
if (methodOrConstructor instanceof Method) {
|
||||||
return LookupFactory.lookup().unreflect((Method) methodOrConstructor);
|
return LookupUtil.lookup().unreflect((Method) methodOrConstructor);
|
||||||
} else {
|
} else {
|
||||||
return LookupFactory.lookup().unreflectConstructor((Constructor<?>) methodOrConstructor);
|
return LookupUtil.lookup().unreflectConstructor((Constructor<?>) methodOrConstructor);
|
||||||
}
|
}
|
||||||
} catch (final IllegalAccessException e) {
|
} catch (final IllegalAccessException e) {
|
||||||
throw new UtilException(e);
|
throw new UtilException(e);
|
||||||
@@ -80,7 +81,7 @@ public class MethodHandleUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MethodHandle handle = null;
|
MethodHandle handle = null;
|
||||||
final MethodHandles.Lookup lookup = LookupFactory.lookup(callerClass);
|
final MethodHandles.Lookup lookup = LookupUtil.lookup(callerClass);
|
||||||
try {
|
try {
|
||||||
handle = lookup.findVirtual(callerClass, name, type);
|
handle = lookup.findVirtual(callerClass, name, type);
|
||||||
} catch (final IllegalAccessException | NoSuchMethodException ignore) {
|
} catch (final IllegalAccessException | NoSuchMethodException ignore) {
|
||||||
@@ -129,7 +130,7 @@ public class MethodHandleUtil {
|
|||||||
* @return 构造方法句柄
|
* @return 构造方法句柄
|
||||||
*/
|
*/
|
||||||
public static MethodHandle findConstructor(final Class<?> callerClass, final MethodType type) {
|
public static MethodHandle findConstructor(final Class<?> callerClass, final MethodType type) {
|
||||||
final MethodHandles.Lookup lookup = LookupFactory.lookup(callerClass);
|
final MethodHandles.Lookup lookup = LookupUtil.lookup(callerClass);
|
||||||
try {
|
try {
|
||||||
return lookup.findConstructor(callerClass, type);
|
return lookup.findConstructor(callerClass, type);
|
||||||
} catch (final NoSuchMethodException e) {
|
} catch (final NoSuchMethodException e) {
|
||||||
@@ -252,7 +253,7 @@ public class MethodHandleUtil {
|
|||||||
public static <T> T invoke(final boolean isSpecial, final Object obj, final Method method, final Object... args) {
|
public static <T> T invoke(final boolean isSpecial, final Object obj, final Method method, final Object... args) {
|
||||||
Assert.notNull(method, "Method must be not null!");
|
Assert.notNull(method, "Method must be not null!");
|
||||||
final Class<?> declaringClass = method.getDeclaringClass();
|
final Class<?> declaringClass = method.getDeclaringClass();
|
||||||
final MethodHandles.Lookup lookup = LookupFactory.lookup(declaringClass);
|
final MethodHandles.Lookup lookup = LookupUtil.lookup(declaringClass);
|
||||||
try {
|
try {
|
||||||
MethodHandle handle = isSpecial ? lookup.unreflectSpecial(method, declaringClass)
|
MethodHandle handle = isSpecial ? lookup.unreflectSpecial(method, declaringClass)
|
||||||
: lookup.unreflect(method);
|
: lookup.unreflect(method);
|
||||||
|
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.core.reflect.lookup;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}<br>
|
||||||
|
* 在调用findSpecial和unreflectSpecial时会出现权限不够问题,抛出"no private access for invokespecial"异常<br>
|
||||||
|
* 所以通过反射创建MethodHandles.Lookup解决该问题。
|
||||||
|
* <p>
|
||||||
|
* 参考:https://blog.csdn.net/u013202238/article/details/108687086
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class ConstructorLookupFactory implements LookupFactory {
|
||||||
|
|
||||||
|
private static final int ALLOWED_MODES = MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
|
||||||
|
| MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC;
|
||||||
|
|
||||||
|
private final Constructor<MethodHandles.Lookup> lookupConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*/
|
||||||
|
public ConstructorLookupFactory() {
|
||||||
|
this.lookupConstructor = createLookupConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup lookup(final Class<?> callerClass) {
|
||||||
|
try {
|
||||||
|
return lookupConstructor.newInstance(callerClass, ALLOWED_MODES);
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new IllegalStateException("no 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Constructor<MethodHandles.Lookup> createLookupConstructor() {
|
||||||
|
final Constructor<MethodHandles.Lookup> constructor;
|
||||||
|
try {
|
||||||
|
constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
|
||||||
|
} catch (final NoSuchMethodException e) {
|
||||||
|
//可能是jdk8 以下版本
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"There is no 'Lookup(Class, int)' constructor in java.lang.invoke.MethodHandles.", e);
|
||||||
|
}
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.core.reflect.lookup;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link MethodHandles.Lookup}方法工厂,用于创建{@link MethodHandles.Lookup}对象<br>
|
||||||
|
* {@link MethodHandles.Lookup}是一个方法句柄查找对象,用于在指定类中查找符合给定方法名称、方法类型的方法句柄。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 参考:https://blog.csdn.net/u013202238/article/details/108687086
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public interface LookupFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
||||||
|
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
||||||
|
*
|
||||||
|
* @param callerClass 被调用的类或接口
|
||||||
|
* @return {@link MethodHandles.Lookup}
|
||||||
|
*/
|
||||||
|
MethodHandles.Lookup lookup(final Class<?> callerClass);
|
||||||
|
}
|
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.core.reflect.lookup;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.lang.caller.CallerUtil;
|
||||||
|
import org.dromara.hutool.core.util.JdkUtil;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link MethodHandles.Lookup}工厂工具,用于创建{@link MethodHandles.Lookup}对象<br>
|
||||||
|
* {@link MethodHandles.Lookup}是一个方法句柄查找对象,用于在指定类中查找符合给定方法名称、方法类型的方法句柄。
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
||||||
|
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 参考:https://blog.csdn.net/u013202238/article/details/108687086
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class LookupUtil {
|
||||||
|
|
||||||
|
private static final LookupFactory factory;
|
||||||
|
|
||||||
|
static {
|
||||||
|
if (JdkUtil.IS_JDK8) {
|
||||||
|
factory = new ConstructorLookupFactory();
|
||||||
|
} else {
|
||||||
|
factory = new MethodLookupFactory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
||||||
|
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
||||||
|
*
|
||||||
|
* @return {@link MethodHandles.Lookup}
|
||||||
|
*/
|
||||||
|
public static MethodHandles.Lookup lookup() {
|
||||||
|
return lookup(CallerUtil.getCaller());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jdk8中如果直接调用{@link MethodHandles#lookup()}获取到的{@link MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
||||||
|
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
||||||
|
*
|
||||||
|
* @param callerClass 被调用的类或接口
|
||||||
|
* @return {@link MethodHandles.Lookup}
|
||||||
|
*/
|
||||||
|
public static MethodHandles.Lookup lookup(final Class<?> callerClass) {
|
||||||
|
return factory.lookup(callerClass);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dromara.hutool.core.reflect.lookup;
|
||||||
|
|
||||||
|
import org.dromara.hutool.core.exceptions.UtilException;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jdk11中直接调用MethodHandles.lookup()获取到的MethodHandles.Lookup只能对接口类型才会权限获取方法的方法句柄MethodHandle。
|
||||||
|
* 如果是普通类型Class,需要使用jdk9开始提供的 MethodHandles#privateLookupIn(java.lang.Class, java.lang.invoke.MethodHandles.Lookup)方法.
|
||||||
|
* <p>
|
||||||
|
* 参考:https://blog.csdn.net/u013202238/article/details/108687086
|
||||||
|
*
|
||||||
|
* @author looly
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
public class MethodLookupFactory implements LookupFactory {
|
||||||
|
|
||||||
|
private final Method privateLookupInMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*/
|
||||||
|
public MethodLookupFactory() {
|
||||||
|
this.privateLookupInMethod = createJdk9PrivateLookupInMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup lookup(final Class<?> callerClass) {
|
||||||
|
try {
|
||||||
|
return (MethodHandles.Lookup) privateLookupInMethod.invoke(MethodHandles.class, callerClass, MethodHandles.lookup());
|
||||||
|
} catch (final IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new UtilException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("JavaReflectionMemberAccess")
|
||||||
|
private static Method createJdk9PrivateLookupInMethod() {
|
||||||
|
try {
|
||||||
|
return MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
|
||||||
|
} catch (final NoSuchMethodException e) {
|
||||||
|
//可能是jdk9 以下版本
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"There is no 'privateLookupIn(Class, Lookup)' method in java.lang.invoke.MethodHandles.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||||
|
* Hutool is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||||
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||||
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link java.lang.invoke.MethodHandles.Lookup} 创建封装<br>
|
||||||
|
* <p>
|
||||||
|
* jdk8中如果直接调用{@link java.lang.invoke.MethodHandles#lookup()}获取到的{@link java.lang.invoke.MethodHandles.Lookup}在调用findSpecial和unreflectSpecial
|
||||||
|
* 时会出现权限不够问题,抛出"no private access for invokespecial"异常,因此针对JDK8及JDK9+分别封装lookup方法。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* 参考:
|
||||||
|
* <p><a href="https://blog.csdn.net/u013202238/article/details/108687086">https://blog.csdn.net/u013202238/article/details/108687086</a></p>
|
||||||
|
*/
|
||||||
|
package org.dromara.hutool.core.reflect.lookup;
|
Reference in New Issue
Block a user