mirror of
https://gitee.com/dromara/hutool.git
synced 2025-07-30 22:10:27 +08:00
fix code
This commit is contained in:
parent
01f94defd2
commit
3b2160d296
@ -16,13 +16,14 @@ public class FunctionPool {
|
||||
|
||||
/**
|
||||
* 通过{@code String(char[] value, boolean share)}这个内部构造生成一个Lambda函数<br>
|
||||
* 此函数通过传入char[],实现zero-copy的String创建,效率很高。但是要求传入的char[]不可以在其他地方修改。
|
||||
* 此函数通过传入char[],实现zero-copy的String创建,效率很高。但是要求传入的char[]不可以在其他地方修改。<br>
|
||||
* 此函数只支持JKDK8
|
||||
*/
|
||||
public static final BiFunction<char[], Boolean, String> STRING_CREATOR;
|
||||
public static final BiFunction<char[], Boolean, String> STRING_CREATOR_JDK8;
|
||||
|
||||
static {
|
||||
final Constructor<String> constructor = ConstructorUtil.getConstructor(String.class, char[].class, boolean.class);
|
||||
STRING_CREATOR = LambdaFactory.build(BiFunction.class, constructor);
|
||||
STRING_CREATOR_JDK8 = LambdaFactory.build(BiFunction.class, constructor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,6 +34,6 @@ public class FunctionPool {
|
||||
* @return String
|
||||
*/
|
||||
public static String createString(final char[] value) {
|
||||
return STRING_CREATOR.apply(value, true);
|
||||
return STRING_CREATOR_JDK8.apply(value, true);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.hutool.core.reflect;
|
||||
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.util.JdkUtil;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Constructor;
|
||||
@ -24,30 +25,16 @@ public class LookupFactory {
|
||||
private static final int ALLOWED_MODES = MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED
|
||||
| MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC;
|
||||
|
||||
private static Constructor<MethodHandles.Lookup> java8LookupConstructor;
|
||||
private static Method privateLookupInMethod;
|
||||
private static Constructor<MethodHandles.Lookup> jdk8LookupConstructor;
|
||||
|
||||
static {
|
||||
//先查询jdk9 开始提供的java.lang.invoke.MethodHandles.privateLookupIn方法,
|
||||
//如果没有说明是jdk8的版本.(不考虑jdk8以下版本)
|
||||
try {
|
||||
//noinspection JavaReflectionMemberAccess
|
||||
privateLookupInMethod = MethodHandles.class.getMethod("privateLookupIn", Class.class, MethodHandles.Lookup.class);
|
||||
} catch (final NoSuchMethodException ignore) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
//jdk8
|
||||
//这种方式其实也适用于jdk9及以上的版本,但是上面优先,可以避免 jdk9 反射警告
|
||||
if (privateLookupInMethod == null) {
|
||||
try {
|
||||
java8LookupConstructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
|
||||
java8LookupConstructor.setAccessible(true);
|
||||
} catch (final NoSuchMethodException e) {
|
||||
//可能是jdk8 以下版本
|
||||
throw new IllegalStateException(
|
||||
"There is neither 'privateLookupIn(Class, Lookup)' nor 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.", e);
|
||||
}
|
||||
if(JdkUtil.isJdk8()){
|
||||
// jdk8 这种方式其实也适用于jdk9及以上的版本,但是上面优先,可以避免 jdk9 反射警告
|
||||
jdk8LookupConstructor = createJdk8LookupConstructor();
|
||||
} else {
|
||||
// jdk9+ 开始提供的java.lang.invoke.MethodHandles.privateLookupIn方法
|
||||
privateLookupInMethod = createJdk9PrivateLookupInMethod();
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,9 +56,33 @@ public class LookupFactory {
|
||||
}
|
||||
//jdk 8
|
||||
try {
|
||||
return java8LookupConstructor.newInstance(callerClass, ALLOWED_MODES);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -22,17 +22,6 @@ import java.lang.reflect.Method;
|
||||
*/
|
||||
public class MethodHandleUtil {
|
||||
|
||||
/**
|
||||
* 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 LookupFactory.lookup(callerClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找指定方法的方法句柄<br>
|
||||
* 此方法只会查找:
|
||||
@ -53,7 +42,7 @@ public class MethodHandleUtil {
|
||||
}
|
||||
|
||||
MethodHandle handle = null;
|
||||
final MethodHandles.Lookup lookup = lookup(callerClass);
|
||||
final MethodHandles.Lookup lookup = LookupFactory.lookup(callerClass);
|
||||
try {
|
||||
handle = lookup.findVirtual(callerClass, name, type);
|
||||
} catch (final IllegalAccessException | NoSuchMethodException ignore) {
|
||||
@ -102,7 +91,7 @@ public class MethodHandleUtil {
|
||||
* @return 构造方法句柄
|
||||
*/
|
||||
public static MethodHandle findConstructor(final Class<?> callerClass, final MethodType type) {
|
||||
final MethodHandles.Lookup lookup = lookup(callerClass);
|
||||
final MethodHandles.Lookup lookup = LookupFactory.lookup(callerClass);
|
||||
try {
|
||||
return lookup.findConstructor(callerClass, type);
|
||||
} catch (final NoSuchMethodException e) {
|
||||
@ -208,7 +197,7 @@ public class MethodHandleUtil {
|
||||
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!");
|
||||
final Class<?> declaringClass = method.getDeclaringClass();
|
||||
final MethodHandles.Lookup lookup = lookup(declaringClass);
|
||||
final MethodHandles.Lookup lookup = LookupFactory.lookup(declaringClass);
|
||||
try {
|
||||
MethodHandle handle = isSpecial ? lookup.unreflectSpecial(method, declaringClass)
|
||||
: lookup.unreflect(method);
|
||||
|
50
hutool-core/src/main/java/cn/hutool/core/util/JdkUtil.java
Executable file
50
hutool-core/src/main/java/cn/hutool/core/util/JdkUtil.java
Executable file
@ -0,0 +1,50 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import cn.hutool.core.text.StrUtil;
|
||||
|
||||
/**
|
||||
* JDK相关工具类,包括判断JDK版本等<br>
|
||||
* 工具部分方法来自fastjson2的JDKUtils
|
||||
*
|
||||
* @author fastjson, looly
|
||||
*/
|
||||
public class JdkUtil {
|
||||
/**
|
||||
* JDK版本
|
||||
*/
|
||||
public static final int JVM_VERSION;
|
||||
|
||||
static {
|
||||
JVM_VERSION = _getJvmVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否JDK8
|
||||
*
|
||||
* @return 是否JDK8
|
||||
*/
|
||||
public static boolean isJdk8() {
|
||||
return 8 == JVM_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据{@code java.specification.version}属性值,获取版本号
|
||||
*
|
||||
* @return 版本号
|
||||
*/
|
||||
private static int _getJvmVersion() {
|
||||
int jvmVersion = -1;
|
||||
|
||||
String javaSpecVer = System.getProperty("java.specification.version");
|
||||
if (StrUtil.isNotBlank(javaSpecVer)) {
|
||||
if (javaSpecVer.startsWith("1.")) {
|
||||
javaSpecVer = javaSpecVer.substring(2);
|
||||
}
|
||||
if (javaSpecVer.indexOf('.') == -1) {
|
||||
jvmVersion = Integer.parseInt(javaSpecVer);
|
||||
}
|
||||
}
|
||||
|
||||
return jvmVersion;
|
||||
}
|
||||
}
|
12
hutool-core/src/test/java/cn/hutool/core/util/JdkUtilTest.java
Executable file
12
hutool-core/src/test/java/cn/hutool/core/util/JdkUtilTest.java
Executable file
@ -0,0 +1,12 @@
|
||||
package cn.hutool.core.util;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class JdkUtilTest {
|
||||
@Test
|
||||
public void jvmVersionTest() {
|
||||
final int jvmVersion = JdkUtil.JVM_VERSION;
|
||||
Assert.assertTrue(jvmVersion >= 8);
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@
|
||||
<dependency>
|
||||
<groupId>com.alibaba.fastjson2</groupId>
|
||||
<artifactId>fastjson2</artifactId>
|
||||
<version>2.0.24</version>
|
||||
<version>2.0.25</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
Loading…
Reference in New Issue
Block a user