通过反射调用Java记录的规范构造函数并不是一个日常任务。然而,从JDK 16开始,这可以相当容易地完成,JDK 16在java.lang.Class中提供了RecordComponent[] getRecordComponents()方法。正如其名称和签名所示,此方法返回表示当前Java记录组件的java.lang.reflect.RecordComponent数组。有了这个组件数组,我们可以调用众所周知的getDeclaredConstructor()方法来识别以这个组件数组作为参数的构造函数。那就是规范构造函数。将这些陈述付诸实践的代码由Java文档本身提供,因此没有必要重新发明它。这是它的代码:
// 这个方法来自JDK的官方文档// https://docs.oracle.com/en/java/javase/19/docs/api/ java.base/java/lang/Class.html#getRecordComponents()public static <T extends Record> Constructor<T> getCanonicalConstructor(Class<T> cls) throws NoSuchMethodException { Class<?>[] paramTypes = Arrays.stream(cls.getRecordComponents()) .map(RecordComponent::getType) .toArray(Class<?>[]::new); return cls.getDeclaredConstructor(paramTypes);}
考虑以下记录:
public record MelonRecord(String type, float weight) {}public record MelonMarketRecord( List<MelonRecord> melons, String country) {}
通过前面的解决方案查找和调用这些记录的规范构造函数可以这样做:
Constructor<MelonRecord> cmr = Records.getCanonicalConstructor(MelonRecord.class);MelonRecord m1 = cmr.newInstance("Gac", 5000f);MelonRecord m2 = cmr.newInstance("Hemi", 1400f); Constructor<MelonMarketRecord> cmmr = Records.getCanonicalConstructor(MelonMarketRecord.class); MelonMarketRecord mm = cmmr.newInstance( List.of(m1, m2), "China");
如果你需要对Java反射原则进行深入的覆盖,那么考虑《Java编码问题》,第一版,第7章。