Skip to content

Commit 7d0a9d3

Browse files
committed
modernize ReflectHelper
we no longer need to use reflection to get at java.lang.Record or java.lang.RecordComponent
1 parent 263ca85 commit 7d0a9d3

File tree

8 files changed

+35
-59
lines changed

8 files changed

+35
-59
lines changed

hibernate-core/src/main/java/org/hibernate/boot/model/internal/AggregateComponentSecondPass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ private void orderColumns(UserDefinedObjectType userDefinedType, int[] originalO
245245
final String[] structColumnNames = component.getStructColumnNames();
246246
if ( structColumnNames == null || structColumnNames.length == 0 ) {
247247
final int[] propertyMappingIndex;
248-
if ( ReflectHelper.isRecord( componentClass ) ) {
248+
if ( componentClass.isRecord() ) {
249249
if ( originalOrder == null ) {
250250
propertyMappingIndex = null;
251251
}

hibernate-core/src/main/java/org/hibernate/internal/util/ReflectHelper.java

Lines changed: 28 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import jakarta.persistence.Transient;
3232

3333
import static java.beans.Introspector.decapitalize;
34+
import static java.lang.Character.isLowerCase;
3435
import static java.lang.Thread.currentThread;
3536

3637
/**
@@ -51,10 +52,6 @@ public final class ReflectHelper {
5152

5253
private static final Method OBJECT_EQUALS;
5354
private static final Method OBJECT_HASHCODE;
54-
private static final Class<?> RECORD_CLASS;
55-
private static final Method GET_RECORD_COMPONENTS;
56-
private static final Method GET_NAME;
57-
private static final Method GET_TYPE;
5855

5956
static {
6057
Method eq;
@@ -68,25 +65,6 @@ public final class ReflectHelper {
6865
}
6966
OBJECT_EQUALS = eq;
7067
OBJECT_HASHCODE = hash;
71-
72-
Class<?> recordClass = null;
73-
Method getRecordComponents = null;
74-
Method getName = null;
75-
Method getType = null;
76-
try {
77-
recordClass = Class.forName( "java.lang.Record" );
78-
getRecordComponents = Class.class.getMethod( "getRecordComponents" );
79-
final Class<?> recordComponentClass = Class.forName( "java.lang.reflect.RecordComponent" );
80-
getName = recordComponentClass.getMethod( "getName" );
81-
getType = recordComponentClass.getMethod( "getType" );
82-
}
83-
catch (Exception e) {
84-
// Ignore
85-
}
86-
RECORD_CLASS = recordClass;
87-
GET_RECORD_COMPONENTS = getRecordComponents;
88-
GET_NAME = getName;
89-
GET_TYPE = getType;
9068
}
9169

9270
/**
@@ -132,7 +110,7 @@ public static boolean overridesEquals(Class<?> clazz) {
132110
equals = extractEqualsMethod( clazz );
133111
}
134112
catch ( NoSuchMethodException nsme ) {
135-
return false; //it's an interface so we can't really tell anything
113+
return false; //it's an interface, so we can't really tell anything
136114
}
137115
return !OBJECT_EQUALS.equals( equals );
138116
}
@@ -152,7 +130,7 @@ public static boolean overridesHashCode(Class<?> clazz) {
152130
hashCode = extractHashCodeMethod( clazz );
153131
}
154132
catch ( NoSuchMethodException nsme ) {
155-
return false; //it's an interface so we can't really tell anything
133+
return false; //it's an interface, so we can't really tell anything
156134
}
157135
return !OBJECT_HASHCODE.equals( hashCode );
158136
}
@@ -185,7 +163,7 @@ public static boolean implementsInterface(Class<?> clazz, Class<?> intf) {
185163
*/
186164
public static Class<?> classForName(String name, Class<?> caller) throws ClassNotFoundException {
187165
try {
188-
final ClassLoader classLoader = currentThread().getContextClassLoader();
166+
final var classLoader = currentThread().getContextClassLoader();
189167
if ( classLoader != null ) {
190168
return classLoader.loadClass( name );
191169
}
@@ -212,7 +190,7 @@ public static Class<?> classForName(String name, Class<?> caller) throws ClassNo
212190
@Deprecated
213191
public static Class<?> classForName(String name) throws ClassNotFoundException {
214192
try {
215-
final ClassLoader classLoader = currentThread().getContextClassLoader();
193+
final var classLoader = currentThread().getContextClassLoader();
216194
if ( classLoader != null ) {
217195
return classLoader.loadClass(name);
218196
}
@@ -250,7 +228,7 @@ public static Class<?> reflectedPropertyClass(
250228
String name,
251229
ClassLoaderService classLoaderService) throws MappingException {
252230
try {
253-
final Class<?> clazz = classLoaderService.classForName( className );
231+
final var clazz = classLoaderService.classForName( className );
254232
return getter( clazz, name ).getReturnTypeClass();
255233
}
256234
catch ( ClassLoadingException e ) {
@@ -263,7 +241,7 @@ public static java.lang.reflect.Type reflectedPropertyType(
263241
String name,
264242
ClassLoaderService classLoaderService) throws MappingException {
265243
try {
266-
final Class<?> clazz = classLoaderService.classForName( className );
244+
final var clazz = classLoaderService.classForName( className );
267245
return getter( clazz, name ).getReturnType();
268246
}
269247
catch ( ClassLoadingException e ) {
@@ -348,7 +326,8 @@ public static <T> Supplier<T> getDefaultSupplier(Class<T> clazz) {
348326
*/
349327
public static boolean isAbstractClass(Class<?> clazz) {
350328
final int modifier = clazz.getModifiers();
351-
return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
329+
return Modifier.isAbstract( modifier )
330+
|| Modifier.isInterface( modifier );
352331
}
353332

354333
/**
@@ -460,7 +439,7 @@ public static Method findGetterMethod(Class<?> containerClass, String propertyNa
460439
Class<?> checkClass = containerClass;
461440
Method getter = null;
462441

463-
if ( isRecord( containerClass ) ) {
442+
if ( containerClass.isRecord() ) {
464443
try {
465444
getter = containerClass.getMethod( propertyName, NO_PARAM_SIGNATURE );
466445
}
@@ -503,7 +482,7 @@ public static Method findGetterMethod(Class<?> containerClass, String propertyNa
503482
private static Method getGetterOrNull(Class<?>[] interfaces, String propertyName) {
504483
Method getter = null;
505484
for ( int i = 0; getter == null && i < interfaces.length; ++i ) {
506-
final Class<?> anInterface = interfaces[i];
485+
final var anInterface = interfaces[i];
507486
if ( !shouldSkipInterfaceCheck( anInterface ) ) {
508487
getter = getGetterOrNull( anInterface, propertyName );
509488
if ( getter == null ) {
@@ -526,7 +505,7 @@ private static Method getGetterOrNull(Class<?>[] interfaces, String propertyName
526505
* @throws MappingException If the {@code containerClass} has both a get- and an is- form.
527506
*/
528507
public static Method getGetterOrNull(Class<?> containerClass, String propertyName) {
529-
if ( isRecord( containerClass ) ) {
508+
if ( containerClass.isRecord() ) {
530509
try {
531510
return containerClass.getMethod( propertyName, NO_PARAM_SIGNATURE );
532511
}
@@ -579,7 +558,8 @@ public static void verifyNoIsVariantExists(
579558
// verify that the Class<?> does not also define a method with the same stem name with 'is'
580559
try {
581560
final Method isMethod = containerClass.getDeclaredMethod( "is" + stemName );
582-
if ( !Modifier.isStatic( isMethod.getModifiers() ) && isMethod.getAnnotation( Transient.class ) == null ) {
561+
if ( !Modifier.isStatic( isMethod.getModifiers() )
562+
&& isMethod.getAnnotation( Transient.class ) == null ) {
583563
// No such method should throw the caught exception. So if we get here, there was
584564
// such a method.
585565
checkGetAndIsVariants( containerClass, propertyName, getMethod, isMethod );
@@ -768,7 +748,7 @@ public static Method findSetterMethod(final Class<?> containerClass, final Strin
768748
private static Method setterOrNull(Class<?>[] interfaces, String propertyName, Class<?> propertyType, String likelyMethodName) {
769749
Method setter = null;
770750
for ( int i = 0; setter == null && i < interfaces.length; ++i ) {
771-
final Class<?> anInterface = interfaces[i];
751+
final var anInterface = interfaces[i];
772752
if ( !shouldSkipInterfaceCheck( anInterface ) ) {
773753
setter = setterOrNull( anInterface, propertyName, propertyType, likelyMethodName );
774754
if ( setter == null ) {
@@ -807,7 +787,7 @@ private static Method setterOrNull(Class<?> theClass, String propertyName, Class
807787

808788
private static String likelySetterMethodNameForProperty(final String propertyName) {
809789
final char firstCharacter = propertyName.charAt( 0 );
810-
return Character.isLowerCase( firstCharacter )
790+
return isLowerCase( firstCharacter )
811791
? "set" + Character.toUpperCase( firstCharacter ) + propertyName.substring( 1 )
812792
: "set" + propertyName;
813793
}
@@ -820,7 +800,8 @@ private static String likelySetterMethodNameForProperty(final String propertyNam
820800
* as an abstract - but again, that is such an edge case...
821801
*/
822802
public static Method findGetterMethodForFieldAccess(Field field, String propertyName) {
823-
for ( Method method : field.getDeclaringClass().getDeclaredMethods() ) {
803+
final var declaringClass = field.getDeclaringClass();
804+
for ( Method method : declaringClass.getDeclaredMethods() ) {
824805
if ( method.getParameterCount() == 0 // if the method has parameters, skip it
825806
&& !Modifier.isStatic( method.getModifiers() )
826807
&& method.getReturnType().isAssignableFrom( field.getType() ) ) {
@@ -847,9 +828,9 @@ public static Method findGetterMethodForFieldAccess(Field field, String property
847828
}
848829
}
849830
}
850-
if ( isRecord( field.getDeclaringClass() ) ) {
831+
if ( declaringClass.isRecord() ) {
851832
try {
852-
return field.getDeclaringClass().getMethod( field.getName(), NO_PARAM_SIGNATURE );
833+
return declaringClass.getMethod( field.getName(), NO_PARAM_SIGNATURE );
853834
}
854835
catch (NoSuchMethodException e) {
855836
// Ignore
@@ -859,16 +840,17 @@ public static Method findGetterMethodForFieldAccess(Field field, String property
859840
return null;
860841
}
861842

843+
@Deprecated(forRemoval = true)
862844
public static boolean isRecord(Class<?> declaringClass) {
863-
return RECORD_CLASS != null && RECORD_CLASS.isAssignableFrom( declaringClass );
845+
return declaringClass.isRecord();
864846
}
865847

866848
public static Class<?>[] getRecordComponentTypes(Class<?> javaType) {
867849
try {
868-
final Object[] recordComponents = (Object[]) GET_RECORD_COMPONENTS.invoke( javaType );
869-
final Class<?>[] componentTypes = new Class[recordComponents.length];
850+
final var recordComponents = javaType.getRecordComponents();
851+
final var componentTypes = new Class[recordComponents.length];
870852
for (int i = 0; i < recordComponents.length; i++ ) {
871-
componentTypes[i] = (Class<?>) GET_TYPE.invoke( recordComponents[i] );
853+
componentTypes[i] = recordComponents[i].getType();
872854
}
873855
return componentTypes;
874856
}
@@ -882,10 +864,10 @@ public static Class<?>[] getRecordComponentTypes(Class<?> javaType) {
882864

883865
public static String[] getRecordComponentNames(Class<?> javaType) {
884866
try {
885-
final Object[] recordComponents = (Object[]) GET_RECORD_COMPONENTS.invoke( javaType );
886-
final String[] componentNames = new String[recordComponents.length];
867+
final var recordComponents = javaType.getRecordComponents();
868+
final var componentNames = new String[recordComponents.length];
887869
for (int i = 0; i < recordComponents.length; i++ ) {
888-
componentNames[i] = (String) GET_NAME.invoke( recordComponents[i] );
870+
componentNames[i] = recordComponents[i].getName();
889871
}
890872
return componentNames;
891873
}

hibernate-core/src/main/java/org/hibernate/mapping/Component.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,7 @@ public boolean isSimpleRecord() {
927927
if ( customInstantiator != null ) {
928928
return simpleRecord = false;
929929
}
930-
if ( componentClass == null || !ReflectHelper.isRecord( componentClass ) ) {
930+
if ( componentClass == null || !componentClass.isRecord() ) {
931931
return simpleRecord = false;
932932
}
933933
final String[] recordComponentNames = ReflectHelper.getRecordComponentNames( componentClass );

hibernate-core/src/main/java/org/hibernate/metamodel/internal/ManagedTypeRepresentationResolverStandard.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
2020
import org.hibernate.usertype.CompositeUserType;
2121

22-
import static org.hibernate.internal.util.ReflectHelper.isRecord;
23-
2422
/**
2523
* @author Steve Ebersole
2624
*/
@@ -107,7 +105,7 @@ else if ( compositeUserType != null ) {
107105
return new EmbeddableCompositeUserTypeInstantiator( (CompositeUserType) compositeUserType );
108106
}
109107
else if ( bootDescriptor.getComponentClassName() != null
110-
&& isRecord( bootDescriptor.getComponentClass() ) ) {
108+
&& bootDescriptor.getComponentClass().isRecord() ) {
111109
if ( bootDescriptor.sortProperties() == null ) {
112110
return new EmbeddableInstantiatorRecordStandard( bootDescriptor.getComponentClass() );
113111
}

hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/IdClassRepresentationStrategy.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
import org.hibernate.property.access.spi.PropertyAccess;
2020
import org.hibernate.type.descriptor.java.JavaType;
2121

22-
import static org.hibernate.internal.util.ReflectHelper.isRecord;
23-
2422
/**
2523
* EmbeddableRepresentationStrategy for an IdClass mapping
2624
*/
@@ -34,7 +32,7 @@ public IdClassRepresentationStrategy(
3432
Supplier<String[]> attributeNamesAccess) {
3533
idClassType = idClassEmbeddable.getMappedJavaType();
3634
final var javaTypeClass = idClassType.getJavaTypeClass();
37-
if ( isRecord( javaTypeClass ) ) {
35+
if ( javaTypeClass.isRecord() ) {
3836
instantiator = simplePropertyOrder
3937
? new EmbeddableInstantiatorRecordStandard( javaTypeClass )
4038
: EmbeddableInstantiatorRecordIndirecting.of( javaTypeClass, attributeNamesAccess.get() );

hibernate-core/src/main/java/org/hibernate/property/access/internal/AccessStrategyHelper.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import static org.hibernate.internal.util.ReflectHelper.NO_PARAM_SIGNATURE;
2828
import static org.hibernate.internal.util.ReflectHelper.findField;
2929
import static org.hibernate.internal.util.ReflectHelper.getterMethodOrNull;
30-
import static org.hibernate.internal.util.ReflectHelper.isRecord;
3130

3231
/**
3332
* @author Steve Ebersole
@@ -64,7 +63,7 @@ public static AccessType getAccessType(Class<?> containerJavaType, String proper
6463
}
6564

6665
public static @Nullable AccessType getExplicitAccessType(Class<?> containerClass, String propertyName, @Nullable Field field) {
67-
if ( isRecord( containerClass ) ) {
66+
if ( containerClass.isRecord() ) {
6867
try {
6968
containerClass.getMethod( propertyName, NO_PARAM_SIGNATURE );
7069
return AccessType.PROPERTY;

hibernate-core/src/main/java/org/hibernate/type/ComponentType.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.hibernate.type.spi.CompositeTypeImplementor;
4242

4343
import static jakarta.persistence.metamodel.Type.PersistenceType.EMBEDDABLE;
44-
import static org.hibernate.internal.util.ReflectHelper.isRecord;
4544
import static org.hibernate.internal.util.StringHelper.unqualify;
4645
import static org.hibernate.metamodel.mapping.EntityDiscriminatorMapping.DISCRIMINATOR_ROLE_NAME;
4746

@@ -75,7 +74,7 @@ public class ComponentType extends AbstractType
7574
public ComponentType(Component component, int[] originalPropertyOrder) {
7675
this( component, originalPropertyOrder,
7776
component.getComponentClassName() != null
78-
&& !isRecord( component.getComponentClass() ) );
77+
&& !component.getComponentClass().isRecord() );
7978
}
8079

8180
public ComponentType(Component component, int[] originalPropertyOrder, boolean mutable) {

hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/RegistryHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public <J> MutabilityPlan<J> determineMutabilityPlan(Type javaType, TypeConfigur
6060
return typeConfiguration.createMutabilityPlan( annotation.value() );
6161
}
6262

63-
if ( javaTypeClass.isEnum() || javaTypeClass.isPrimitive() || ReflectHelper.isRecord( javaTypeClass ) ) {
63+
if ( javaTypeClass.isEnum() || javaTypeClass.isPrimitive() || javaTypeClass.isRecord() ) {
6464
return ImmutableMutabilityPlan.instance();
6565
}
6666

0 commit comments

Comments
 (0)