diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/FunctionPool.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/FunctionPool.java
index 02e611cc3..b235ad7d8 100644
--- a/hutool-core/src/main/java/cn/hutool/core/lang/func/FunctionPool.java
+++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/FunctionPool.java
@@ -16,13 +16,14 @@ public class FunctionPool {
/**
* 通过{@code String(char[] value, boolean share)}这个内部构造生成一个Lambda函数
- * 此函数通过传入char[],实现zero-copy的String创建,效率很高。但是要求传入的char[]不可以在其他地方修改。
+ * 此函数通过传入char[],实现zero-copy的String创建,效率很高。但是要求传入的char[]不可以在其他地方修改。
+ * 此函数只支持JKDK8
*/
- public static final BiFunction STRING_CREATOR;
+ public static final BiFunction STRING_CREATOR_JDK8;
static {
final Constructor 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);
}
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/LookupFactory.java b/hutool-core/src/main/java/cn/hutool/core/reflect/LookupFactory.java
index 5c284e18b..7afe7e6c9 100644
--- a/hutool-core/src/main/java/cn/hutool/core/reflect/LookupFactory.java
+++ b/hutool-core/src/main/java/cn/hutool/core/reflect/LookupFactory.java
@@ -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 java8LookupConstructor;
private static Method privateLookupInMethod;
+ private static Constructor 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 createJdk8LookupConstructor(){
+ final Constructor 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;
+ }
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/MethodHandleUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/MethodHandleUtil.java
index 6e7531bec..a0bad42b4 100644
--- a/hutool-core/src/main/java/cn/hutool/core/reflect/MethodHandleUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/reflect/MethodHandleUtil.java
@@ -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);
- }
-
/**
* 查找指定方法的方法句柄
* 此方法只会查找:
@@ -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 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);
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/JdkUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/JdkUtil.java
new file mode 100755
index 000000000..51295aa8f
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/util/JdkUtil.java
@@ -0,0 +1,50 @@
+package cn.hutool.core.util;
+
+import cn.hutool.core.text.StrUtil;
+
+/**
+ * JDK相关工具类,包括判断JDK版本等
+ * 工具部分方法来自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;
+ }
+}
diff --git a/hutool-core/src/test/java/cn/hutool/core/util/JdkUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/JdkUtilTest.java
new file mode 100755
index 000000000..f120c39d6
--- /dev/null
+++ b/hutool-core/src/test/java/cn/hutool/core/util/JdkUtilTest.java
@@ -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);
+ }
+}
diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml
index 5bcec276f..bf9f00ae7 100755
--- a/hutool-json/pom.xml
+++ b/hutool-json/pom.xml
@@ -44,7 +44,7 @@
com.alibaba.fastjson2
fastjson2
- 2.0.24
+ 2.0.25
test