簡體   English   中英

對象在反射java中自動設置為null

[英]Object automatically being set to null in reflection java

我寫了一個反射函數,它在一些預先指定的條件下合並兩個對象:

在迭代對象的字段時,對象 A 的值是正確的,但是一旦當前對象的字段用完並且函數開始迭代下一個對象,即已設置值的字段,它們變為NULL。

在這里,我提供我的反射代碼和主要功能:

public static void mergeObjectAndSet(Object objectA,Object objectB,Set<String> deleteSetA,Set<String> deleteSetB,Set<String> deleteSetC,String path) throws Exception {
    LOGGER.info("In merge Sets and Diff function : ");
    LOGGER.info("Deleted sets A are : "+deleteSetA+" B : "+deleteSetB+" C : "+deleteSetC);
    LOGGER.info("Object A is : "+objectA+" object B is : "+objectB);
    if(null == deleteSetA){
        deleteSetA = new HashSet<>();
    }
    else if(null == deleteSetB){
        deleteSetB = new HashSet<>();
    }

    Class classA = objectA.getClass();
    Class classB = objectB.getClass();

    LOGGER.info("Classes are : "+classA+" class B : "+classB);
    Field objectBFields[] = classB.getDeclaredFields();
    System.out.println(objectA);
    for (Field fieldB : objectBFields) {
        LOGGER.info("fields to be looped in mergeObjectAndSet are : "+objectBFields.toString() +" path is : "+path);
        fieldB.setAccessible(true);
        Class typeB = fieldB.getType();
        Object fieldAObject = fieldB.get(objectA);
        Object fieldBObject = fieldB.get(objectB);

        if (!Collection.class.isAssignableFrom(typeB)) {
            LOGGER.info("passes null check for field objects : ");
            if (isTypePrimitive(typeB)) {
                if(null != fieldAObject || null != fieldBObject) {
                    Field fieldA = classA.getDeclaredField(fieldB.getName());
                    fieldA.setAccessible(true);
                    LOGGER.info("field A is : " + fieldA.getName());
                    if (!(deleteSetA.contains(path + Constants.HYPHEN + fieldA.getName())) && (deleteSetB.contains(path + Constants.HYPHEN + fieldA.getName()))) {
                        LOGGER.info("In only deleted set case : Adding field : " + fieldA.getName() + " to deleted set");
                        deleteSetC.add(path + Constants.HYPHEN + fieldA.getName());
                        LOGGER.info("Merged object for the field : " + fieldB.getName() + " to object : " + fieldBObject + " in object : " + objectA);
                    }else if(deleteSetA.contains(path + Constants.HYPHEN + fieldA.getName()) &&  !(deleteSetB.contains(path + Constants.HYPHEN + fieldA.getName())) && null != fieldBObject && null==fieldAObject) {
                        LOGGER.info("in merge set and objects case : ");
                        fieldA.set(objectA, fieldBObject);
                        LOGGER.info("Merged object for the field for case refresh : " + fieldB.getName() + " to object : " + fieldBObject + " in object : " + objectA);
                    }else if(!(deleteSetA.contains(path + Constants.HYPHEN + fieldA.getName())) &&  !(deleteSetB.contains(path + Constants.HYPHEN + fieldA.getName()))){
                        LOGGER.info("In merge case irrespective of deleted sets : ");
                        fieldA.set(objectA, fieldBObject);
                    }
                }
            } else {
                if ((null==fieldAObject && null==fieldBObject)){
                    LOGGER.info("In both fields are null case : ");
                    LOGGER.info("Field here is : "+fieldB.getName());
                    for(String del : deleteSetA){
                        if(del.startsWith(fieldB.getName())){
                            deleteSetC.addAll(deleteSetA);
                        }
                    }
                    continue;
                }
                LOGGER.info("In non primitive type check : path here for np is : "+path);
                LOGGER.info("field name here : "+fieldB.getName());
                LOGGER.info("path here : "+path);
                LOGGER.info("object name here : "+objectA.getClass().getName());
                Field fieldA = classA.getDeclaredField(fieldB.getName());
                fieldA.setAccessible(true);
                if (null == fieldAObject) {
                    LOGGER.info("if A is null case : initialise it with an instance");
                    Constructor[] constructors = fieldA.getType().getDeclaredConstructors();

                    for (Constructor constructor : constructors) {
                        constructor.setAccessible(true);
                        if (0 == constructor.getParameterCount()) {
                            fieldAObject = constructor.newInstance();
                            break;
                        }
                    }
                }

                LOGGER.info("No test cases met, path is : "+path);

                if (null == path) {
                    LOGGER.info("when path is null new path here is : "+path);
                    mergeObjectAndSet(fieldAObject, fieldBObject, deleteSetA, deleteSetB, deleteSetC, fieldA.getName());

                } else {
                    LOGGER.info("path here when some path is there is : "+path);
                    mergeObjectAndSet(fieldAObject, fieldBObject, deleteSetA, deleteSetB, deleteSetC, path + Constants.HYPHEN + fieldA.getName());
                }
            }
        }
    }
}

主要功能是:

public static void main(String args[]) {
    LeadDetailSRO leadDetailSRO1 = new LeadDetailSRO();
    LeadDetailSRO leadDetailSRO2 = new LeadDetailSRO();
    BankDetailSRO bankDetails = new BankDetailSRO();
    bankDetails.setBeneficiaryName("ars");
    bankDetails.setBranchName("noida");
    leadDetailSRO2.setBankDetails(bankDetails);
    Set<String> deleteSet1 = new HashSet<>();
    Set<String> deleteSet2 = new HashSet<>();
    Set<String> deleteSet3 = new HashSet<>();
    deleteSet1.add("bankDetails-beneficiaryName");
    try {
        System.out.println("Before deletion object 1 is : " + leadDetailSRO1 + " object 2 is : " + leadDetailSRO2+"deleteset A is : "+deleteSet1+" B is : "+deleteSet2+" C is : "+deleteSet3);
        Utils.mergeObjectAndSet(leadDetailSRO1, leadDetailSRO2, deleteSet1, deleteSet2, deleteSet3, null);
        System.out.println("After deletion object 1 is : " + leadDetailSRO1 + " object 2 is : " + leadDetailSRO2+"deleteset A is : "+deleteSet1+" B is : "+deleteSet2+" C is : "+deleteSet3);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

輸出是:

After deletion object 1 is: LeadDetailSRO{
  uploadDocumentList=null,
  businessOwnerDetails=null,
  businessOwnerDetailList=null,
  authorizedSignatoryList=null,
  businessEntityDetails=null,
  leadInfo=null,
  bankDetails=null,
  addressDetails=null,
  cfaAgent=null,
  vaAgent=null,
  auditTrail=null,
  additionalDetails=null,
  additionalQuestions=null,
}
object2 is: LeadDetailSRO{
  uploadDocumentList=null,
  businessOwnerDetails=null,
  businessOwnerDetailList=null,
  authorizedSignatoryList=null,
  businessEntityDetails=null,
  leadInfo=null,
  bankDetails=BankDetailSRO{
    bankName='null',
    bankAccountNumber='null',
    ifscCode='null',
    bankAccountHolder='null',
    beneficiaryName='ars',
    branchName='noida',
    status='null',
    nameMatchStatus='null',
    reEnterAccountNumber='null',
    reEnterIfscCode='null'
  },
  addressDetails=null,
  cfaAgent=null,
  vaAgent=null,
  auditTrail=null,
  additionalDetails=null,
  additionalQuestions=null,
  documents=null,
}
deleteset A is: [
  bankDetails-beneficiaryName
]Bis: [

]Cis: [

]

而預期的輸出是:

After deletion object1 is: LeadDetailSRO{
  uploadDocumentList=null,
  businessOwnerDetails=null,
  businessOwnerDetailList=null,
  authorizedSignatoryList=null,
  businessEntityDetails=null,
  leadInfo=null,
  bankDetails=BankDetailSRO{
    bankName='null',
    bankAccountNumber='null',
    ifscCode='null',
    bankAccountHolder='null',
    beneficiaryName='ars',
    branchName='noida',
    status='null',
    nameMatchStatus='null',
    reEnterAccountNumber='null',
    reEnterIfscCode='null'
  },
  addressDetails=null,
  cfaAgent=null,
  vaAgent=null,
  auditTrail=null,
  additionalDetails=null,
  additionalQuestions=null,
  documents=null,
}
object2 is: LeadDetailSRO{
  uploadDocumentList=null,
  businessOwnerDetails=null,
  businessOwnerDetailList=null,
  authorizedSignatoryList=null,
  businessEntityDetails=null,
  leadInfo=null,
  bankDetails=BankDetailSRO{
    bankName='null',
    bankAccountNumber='null',
    ifscCode='null',
    bankAccountHolder='null',
    beneficiaryName='ars',
    branchName='noida',
    status='null',
    nameMatchStatus='null',
    reEnterAccountNumber='null',
    reEnterIfscCode='null'
  },
  addressDetails=null,
  cfaAgent=null,
  vaAgent=null,
  auditTrail=null,
  additionalDetails=null,
  additionalQuestions=null,
  documents=null,
}
deleteset A is: [
  bankDetails-beneficiaryName
]Bis: [

]Cis: [

]

輸出的差異將在 object1 中看到。 bankDetails LeadDetailSRO是一個類,其中包含BankDetailSRO作為對象,而BankDetailSRO包含字段beneficiaryName , branchName

當 fieldA 為 null 時,您將創建一個新對象,但您從未使用此新實例設置該字段。

引用fieldAObject不再指向fieldAObject中的空值,而是指向您創建的新實例。 但是 objectA 沒有引用這個對象。

你必須明確地寫出來。

if (null == fieldAObject) {
    LOGGER.info("if A is null case : initialise it with an instance");
    Constructor[] constructors = fieldA.getType().getDeclaredConstructors();

    for (Constructor constructor : constructors) {
        constructor.setAccessible(true);
        if (0 == constructor.getParameterCount()) {
            fieldAObject = constructor.newInstance();
            fieldA.set(objectA, fieldAObject); // <-- set the new value
            break;
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM