Maison  >  Article  >  Java  >  Comment attribuer des valeurs aux propriétés d'un objet à l'aide de la réflexion Java ?

Comment attribuer des valeurs aux propriétés d'un objet à l'aide de la réflexion Java ?

WBOY
WBOYavant
2023-05-07 10:43:191878parcourir

Avant-propos

J'ai récemment rencontré un problème dans un projet, qui consiste à implémenter une méthode universelle de conversion des futures langues multilingues. Sur la base de cette exigence, j'ai décidé d'utiliser la réflexion pour l'implémenter et définir des valeurs d'attribut pour les propriétés des objets. basé sur la réflexion. Voici comment Reflection implémente la méthode de définition de la valeur de l'attribut de l'objet

Méthode 1 : Ici, l'attribut Field du côté défini de Field est utilisé, puis la visibilité est définie, puis une valeur est définie, et enfin imprimé

//Attribuer la variable à l'objet objet Attribuer une valeur à un champ

f.set(object, value);

//Après avoir obtenu l'instance de la classe Field, vous pouvez y appeler la méthode

//Méthode : get(Object obj) renvoie l'objet spécifié obj La valeur du champ représenté par Field

package com.example.reflectiondemo;
 
import java.lang.reflect.Field;
 
/**
 * @program my-project-model
 * @description:
 * @author: lee
 * @create: 2023/01/04 19:52
 */
public class ReflectMain {
 
    private String readOnly;
 
    public String getReadOnly() {
        return readOnly;
    }
 
    public void setReadOnly(String readOnly) {
        System.out.println("set");
        this.readOnly = readOnly;
    }
 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        ReflectMain t = new ReflectMain();
        Field f = t.getClass().getDeclaredField("readOnly");
        f.setAccessible(true);
        f.set(t, "test");
        System.out.println(t.getReadOnly());
 
    }
}

Méthode 2 : Utilisez la méthode d'invocation

package com.example.reflectiondemo;
 
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
 
/**
 * @program my-project-model
 * @description:
 * @author: lee
 * @create: 2023/01/04 19:52
 */
public class ReflectMain {
 
    private String readOnly;
 
    public String getReadOnly() {
        return readOnly;
    }
 
    public void setReadOnly(String readOnly) {
        System.out.println("set");
        this.readOnly = readOnly;
    }
 
    //    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//        ReflectMain t = new ReflectMain();
//        Field f = t.getClass().getDeclaredField("readOnly");
//        f.setAccessible(true);
//        f.set(t, "test");
//        System.out.println(t.getReadOnly());
//
//    }
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ReflectMain t = new ReflectMain();
        Method setReadOnly = t.getClass().getMethod("setReadOnly", String.class);
        String s = "test2";
        setReadOnly.invoke(t, s);
        System.out.println(t.getReadOnly());
 
    }
}

Comment attribuer des valeurs aux propriétés dun objet à laide de la réflexion Java ?

On peut voir qu'en utilisant la réflexion, nous pouvons définissez facilement chaque attribut, même pour les attributs privés, nous pouvons facilement définir la valeur de l'attribut. Utilisons cet exemple de démonstration pour configurer notre fonction initiale.

Résumé :

C'est-à-dire que la première méthode termine l'affectation sans appeler la méthode set de l'attribut,

mais la deuxième méthode termine l'affectation en appelant la méthode set de l'attribut.

Donc, si vous souhaitez modifier la valeur des attributs du programme dans le programme et souhaitez également faire des choses supplémentaires, vous pouvez écrire ces choses dans la méthode set et utiliser la deuxième méthode

public class MultiLangContentUtil {
 
    /**
     * 从PO查询数据赋值到DTO
     * 注意!!这里的多语字段根据
     * 简体中文的变量名 英文名和繁体名需要根据规则进行 指定
     * 规则如下
     * 英文名=简体中文名2
     * 繁体名=简体中文名3
     *
     * @param targetPO        数据库中查询出的数据
     * @param targetDTO       将要转换的对象DTO
     * @param targetMultiName 需要展示的多语字段
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void setMultiLangDTOName(Object targetPO, Object targetDTO, String targetMultiName) {
        try {
 
            String locale = MultiLangContentUtil.getLocale();
            Class<?> targetDTOClass = targetDTO.getClass();
            Class<?> targetPOClass = targetPO.getClass();
            //这里是将targetMultiName进行展示
            Field declaredFieldDTO = targetDTOClass.getDeclaredField(targetMultiName);
            declaredFieldDTO.setAccessible(true);
            switch (locale) {
                case ZH_CN:
                    //获取PO的值
                    Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName);
                    //获取DTO对象
                    declaredFieldPO.setAccessible(true);
                    //对DTO根据PO进行设置
                    declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO));
                    break;
                case EN_US:
                    //获取PO的值
                    Field declaredFieldPO2 = targetPOClass.getDeclaredField(targetMultiName + 2);
                    //获取DTO对象
                    declaredFieldPO2.setAccessible(true);
                    //对DTO根据PO进行设置
                    declaredFieldDTO.set(targetDTO, declaredFieldPO2.get(targetPO));
                    break;
                case ZH_TW:
                    //获取PO的值
                    Field declaredFieldPO3 = targetPOClass.getDeclaredField(targetMultiName + 3);
                    //获取DTO对象
                    declaredFieldPO3.setAccessible(true);
                    //对DTO根据PO进行设置
                    declaredFieldDTO.set(targetDTO, declaredFieldPO3.get(targetPO));
                    break;
                default:
                    break;
            }
            //防止没有抽取多语的情况下没有参照返回,默认情况下设置中文
            if (StringUtils.isBlank((String) declaredFieldDTO.get(targetDTO))) {
                //获取PO的值
                Field declaredFieldPO = targetPOClass.getDeclaredField(targetMultiName);
                //获取DTO对象
                declaredFieldPO.setAccessible(true);
                //对DTO根据PO进行设置
                declaredFieldDTO.set(targetDTO, declaredFieldPO.get(targetPO));
            }
        } catch (NoSuchFieldException e) {
            log.error("查询当前字段--->{}不存在{},", targetMultiName, e);
        } catch (IllegalAccessException e) {
            log.error("查询字段--->{}多语时发生非法状态异常{},", targetMultiName, e);
        } catch (Exception e) {
            log.error("查询字段{}多语时发生错误{},", targetMultiName, e);
        } catch (Throwable throwable) {
            log.error("查询多语言字段{}发生未知错误{}", targetMultiName, ThrowableUtil.stackTraceToString(throwable));
        }
    }
 
    /**
     * 更新多语字段
     *
     * @param targetDTO     需要转换的字段
     * @param targetPO      数据库PO
     * @param fieldName     多语字段
     * @param MultiLangSize 多语字段的数量
     */
    public static void updateMultiLang(Object targetDTO, Object targetPO, String fieldName, Integer MultiLangSize) {
        try {
            Class<?> targetDTOClass = targetDTO.getClass();
            Class<?> targetPOClass = targetPO.getClass();
 
            Field dtoClassField = targetDTOClass.getDeclaredField(fieldName);
            dtoClassField.setAccessible(true);
            if (StringUtils.isNotBlank((String) dtoClassField.get(targetDTO))) {
                Field poClassField = targetPOClass.getDeclaredField(fieldName);
                poClassField.setAccessible(true);
                poClassField.set(targetPO, dtoClassField.get(targetDTO));
            }
            for (int i = 2; i <= MultiLangSize; i++) {
                Field dtoClassField2 = targetDTOClass.getDeclaredField(fieldName + i);
                dtoClassField2.setAccessible(true);
                if (StringUtils.isNotBlank((String) dtoClassField2.get(targetDTO))) {
                    Field poClassField2 = targetPOClass.getDeclaredField(fieldName + i);
                    poClassField2.setAccessible(true);
                    poClassField2.set(targetPO, dtoClassField2.get(targetDTO));
                }
            }
        } catch (NoSuchFieldException e) {
            log.error("更新当前字段--->{}不存在{},", fieldName, e);
        } catch (IllegalAccessException e) {
            log.error("更新字段--->{}多语时发生非法状态异常{},", fieldName, e);
        } catch (Exception e) {
            log.error("更新字段{}多语时发生错误{},", fieldName, e);
        } catch (Throwable throwable) {
            log.error("更新多语言字段{}发生未知错误{}", fieldName, ThrowableUtil.stackTraceToString(throwable));
        }
    }
 
    /**
     * 获取本地的语言,默认中文
     * en_US  英文
     * zh_CN  简体中文
     * zh_TW  繁体中文
     *
     * @return
     */
    public static final String getLocale() {
        String locale = InvocationInfoProxy.getLocale();
        return StringUtils.isEmpty(locale) ? "zh_CN" : locale;
    }
}

L'idée de base de ​​cette classe d'outils est

  • Utilisez la méthode get de Field pour obtenir la valeur de l'attribut

  • La méthode set de Field pour définir l'attribut

// Attribuer une valeur à une variable Attribuer une valeur à un champ de l'objet objet

f.set(object, value);

//Après avoir obtenu l'instance de la classe Field, vous pouvez y appeler la méthode

//Méthode : get(Object obj) renvoie la valeur du champ représenté par ce champ sur l'objet spécifié obj

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer