Java のカスタム クラス マッパー
Feb 16 2023
この記事では、MapStruct などのサードパーティ ライブラリを使用せずに、Java でカスタム マッパー util クラスを実装する方法を説明します。まず第一に、Java プログラミング言語と Java Reflection API についての基本的な知識を持っている必要があります。
この記事では、MapStruct などのサードパーティ ライブラリを使用せずに、Java でカスタム マッパー util クラスを実装する方法を説明します。
まず第一に、Java プログラミング言語と Java Reflection API についての基本的な知識を持っている必要があります。
はじめましょう。
public static <O, Target> O map(Object instance, Class<Target> targetClass) {
if (instance.getClass().isPrimitive() || targetClass.isPrimitive()) {
throw new RuntimeException("Provide a non primitive class");
}
if (instance.getClass().isInterface() || targetClass.isInterface()) {
throw new RuntimeException("Provide a non interface class");
}
if (instance.getClass().isEnum() || targetClass.isEnum()) {
throw new RuntimeException("Provide a non enum class");
}
if (Modifier.isAbstract(instance.getClass().getModifiers()) || Modifier.isAbstract(targetClass.getModifiers())) {
throw new RuntimeException("Provide a non abstract class");
}
return doMap(instance, instance.getClass(), targetClass);
}
@SneakyThrows
private static <O, Source, Target> O doMap(Object sourceInstance, Class<Source> sourceClass, Class<Target> targetClass) {
Set<Field> declaredSourceFields = findAllFields(sourceClass);
Set<Field> declaredTargetFields = findAllFields(targetClass);
Object targetInstance = targetClass.getDeclaredConstructor().newInstance();
for (Field field : declaredTargetFields) {
Field sourceField = findSourceField(field, declaredSourceFields);
if (sourceField != null) {
field.setAccessible(true);
field.set(targetInstance, sourceField.get(sourceInstance));
}
}
return (O) targetInstance;
}
public static Set<Field> findAllFields(Class<?> inputClass) {
Set<Field> allFields = new HashSet<>();
if (inputClass == null) {
return allFields;
}
Field[] fields = inputClass.getDeclaredFields();
allFields.addAll(Set.of(fields));
allFields.addAll(findAllFields(inputClass.getSuperclass()));
return allFields;
}
private static Field findSourceField(Field targetField, Set<Field> declaredSourceFields) {
for (Field field : declaredSourceFields) {
field.setAccessible(true);
String sourceFieldName = field.getName();
if (sourceFieldName.equals(targetField.getName()) &&
field.getType().equals(targetField.getType())) {
return field;
}
}
return null;
}
例:
@Setter
@Getter
public class SourceClass {
String surname;
Integer age;
private String name;
@Override
public String toString() {
return "SourceClass{" +
"surname='" + surname + '\'' +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
@Setter
@Getter
public class TargetClass {
Integer age;
private String name;
@Override
public String toString() {
return "TargetClass{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public static void main(String[] args) {
SourceClass sourceInstance = new SourceClass();
sourceInstance.setAge(27);
sourceInstance.setName("Java");
sourceInstance.setSurname("Reflection");
TargetClass targetInstance = CustomMapper.map(sourceInstance, TargetClass.class);
System.out.println(targetInstance);
}
姓はターゲット クラスで使用できないため、出力には存在しません。したがって、map メソッドはこのフィールドを無視します。
結論:
Java で書かれたライブラリ、フレームワーク、IDE のほとんどは Java Reflection API を利用しています。ただし、この API は操作ごとにセキュリティ権限をチェックするため、少し時間がかかります。パフォーマンスを向上させるために、このリンクから Java メソッド ハンドルを確認してください。https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandles.html。
読んでくれてありがとう。
よろしくお願いします

![とにかく、リンクリストとは何ですか?[パート1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































