Skip to content

Commit d65f4e8

Browse files
committed
Call Class.isRecord() when it is available, a few cosmetic changes
1 parent e18a501 commit d65f4e8

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/main/java/org/apache/ibatis/reflection/Reflector.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2021 the original author or authors.
2+
* Copyright 2009-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
1515
*/
1616
package org.apache.ibatis.reflection;
1717

18+
import java.lang.invoke.MethodHandle;
19+
import java.lang.invoke.MethodHandles;
20+
import java.lang.invoke.MethodType;
1821
import java.lang.reflect.Array;
1922
import java.lang.reflect.Constructor;
2023
import java.lang.reflect.Field;
@@ -50,6 +53,7 @@
5053
*/
5154
public class Reflector {
5255

56+
private static final MethodHandle isRecordMethodHandle = getIsRecordMethodHandle();
5357
private final Class<?> type;
5458
private final String[] readablePropertyNames;
5559
private final String[] writablePropertyNames;
@@ -65,10 +69,9 @@ public Reflector(Class<?> clazz) {
6569
type = clazz;
6670
addDefaultConstructor(clazz);
6771
Method[] classMethods = getClassMethods(clazz);
68-
if (this.isRecordType()) {
69-
addAccessorMethods(classMethods);
70-
}
71-
else {
72+
if (isRecord(type)) {
73+
addRecordGetMethods(classMethods);
74+
} else {
7275
addGetMethods(classMethods);
7376
addSetMethods(classMethods);
7477
addFields(clazz);
@@ -83,20 +86,11 @@ public Reflector(Class<?> clazz) {
8386
}
8487
}
8588

86-
// java.lang.Record
87-
88-
private boolean isRecordType() {
89-
Class<?> parent = this.type.getSuperclass();
90-
return null != parent && "java.lang.Record".equals(parent.getName());
91-
}
92-
93-
private void addAccessorMethods(Method[] methods) {
89+
private void addRecordGetMethods(Method[] methods) {
9490
Arrays.stream(methods).filter(m -> m.getParameterTypes().length == 0)
9591
.forEach(m -> addGetMethod(m.getName(), m, false));
9692
}
9793

98-
// non-record
99-
10094
private void addDefaultConstructor(Class<?> clazz) {
10195
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
10296
Arrays.stream(constructors).filter(constructor -> constructor.getParameterTypes().length == 0)
@@ -151,9 +145,6 @@ private void addGetMethod(String name, Method method, boolean isAmbiguous) {
151145
getMethods.put(name, invoker);
152146
Type returnType = TypeParameterResolver.resolveReturnType(method, type);
153147
getTypes.put(name, typeToClass(returnType));
154-
// if (this.isRecordType()) {
155-
// System.out.println("record " + this.type.getSimpleName() + " addGetMethod " + name + " returning " + returnType);
156-
// }
157148
}
158149

159150
private void addSetMethods(Method[] methods) {
@@ -467,4 +458,25 @@ public boolean hasGetter(String propertyName) {
467458
public String findPropertyName(String name) {
468459
return caseInsensitivePropertyMap.get(name.toUpperCase(Locale.ENGLISH));
469460
}
461+
462+
/**
463+
* Class.isRecord() alternative for Java 15 and older.
464+
*/
465+
private static boolean isRecord(Class<?> clazz) {
466+
try {
467+
return isRecordMethodHandle != null && (boolean)isRecordMethodHandle.invokeExact(clazz);
468+
} catch (Throwable e) {
469+
throw new ReflectionException("Failed to invoke 'Class.isRecord()'.", e);
470+
}
471+
}
472+
473+
private static MethodHandle getIsRecordMethodHandle() {
474+
MethodHandles.Lookup lookup = MethodHandles.lookup();
475+
MethodType mt = MethodType.methodType(boolean.class);
476+
try {
477+
return lookup.findVirtual(Class.class, "isRecord", mt);
478+
} catch (NoSuchMethodException | IllegalAccessException e) {
479+
return null;
480+
}
481+
}
470482
}

0 commit comments

Comments
 (0)