有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

对象在反射java中自动设置为null

我编写了一个反射函数,它在一些预先指定的条件下合并两个对象:

在对象的字段上迭代时,观察到的对象A的值是正确的,但一旦当前对象的字段用完,函数开始在下一个对象上迭代,即设置了值的字段,它们就会变为空

这里,我提供了我的反射代码和主要功能:

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包含beneficiaryNamebranchName字段


共 (1) 个答案

  1. # 1 楼答案

    当fieldA为null时,您将创建一个新对象,但从未使用此新实例设置该字段

    引用fieldAObject不再指向fieldA中的空值,而是指向您创建的新实例。但是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;
            }
        }