Java Reflection: проверьте, создан ли объект уже

   BeanInfo componentBeanInfo = null;
   List<String> propNames =new ArrayList<String>();
   Object nestedObject=null;
            try {
            componentBeanInfo = Introspector.getBeanInfo(sourceObject.getClass());  
            final PropertyDescriptor[] props=componentBeanInfo.getPropertyDescriptors();
            String [] parameters = getParameters(); //ObjectA.code="abc",ObjectA.type="single"
            for (String parameter : parameters) {
                boolean isNestedField = isNestedPropertyRead(parameter);
                for(PropertyDescriptor prop : props){
                    if(isNestedField){
                        String[] fullParam = parameter.split("\\.");//ObjectA.code
                        String nestedObj = fullParam[0];//ObjectA
                        String nestObjField = fullParam[1];//code
                        if(nestedObj.equalsIgnoreCase(prop.getName())){
                            Class<?> classType = Class.forName(prop.getPropertyType().getName());                       
                            BeanInfo nestedBeanInfo;
                            nestedBeanInfo = Introspector.getBeanInfo(classType);
                                final PropertyDescriptor[] nestedProps =nestedBeanInfo.getPropertyDescriptors();
                                    for(PropertyDescriptor nestedProp : nestedProps){
                                        if(nestedProp.getName().equalsIgnoreCase(nestObjField)){
                                            Class<?> nestedClassType = Class.forName(nestedProp.getPropertyType().getName());
                                            Object value = convertToObject(nestedClassType,value(parameter));
                                            try {                                       
                                                /*if(isNewProperty(prop.getName(),propNames)){
                                                 nestedObject = classType.newInstance();
                                                }*/
                                                if(nestedObject == null) {
                                                nestedObject  = classType.newInstance();
                                                }
                                                nestedProp.getWriteMethod().invoke(nestedObject, value);
                                                prop.getWriteMethod().invoke(sourceObject,nestedObject );
                                            } catch (IllegalArgumentException | InstantiationException | InvocationTargetException e) {
                                                e.printStackTrace();
                                            }
                                          break;
                                        }
                                    }
                            break;
                        }
                    }
                    else if(prop.getName().equalsIgnoreCase(parameter)){                    
                        try {
                            Class<?> classType = Class.forName(prop.getPropertyType().getName());
                            Object value = convertToObject(classType,value(parameter));
                            prop.getWriteMethod().invoke(sourceObject, value);
                            break;
                        } catch (IllegalArgumentException | InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }   
      }catch (IntrospectionException | IllegalAccessException e) {
            e.printStackTrace();
      }

В приведенном выше фрагменте кода я столкнулся с проблемой в следующих строках:

    nestedObject  = classType.newInstance();

Это создает новый экземпляр каждый раз, и из-за этого я в конечном итоге устанавливаю значения для новых вложенных объектов каждый раз, переопределяя предыдущий объект. Как я могу избежать этого и установить значения для уже созданного объекта в цикле. Может ли кто-нибудь предложить, как я могу заставить его работать?

Я обязательно изменю приведенный ниже фрагмент кода также как общий, а не ограничусь одним экземпляром ' . ' в качестве разделителя. Но сначала подумал о правильной логике цикла.

String[] fullParam = parameter.split("\\.");//ObjectA.code
String nestedObj = fullParam[0];//ObjectA
String nestObjField = fullParam[1];//code

ОБНОВЛЕНИЕ-1- @javaguy- Моя структура объекта выглядит так:

public class OuterObject {

private String field1;

private ObjectA field2;

private ObjectB field3;

private String  field4;

...// can have lot of nested objects of different types like ObjectA,ObjectB etc

}

открытый класс ObjectA {

private String field1;

private int field2;

private String field3;

...

}

открытый класс ObjectB {

private String field1;

private String field2;

private String field3;

...

}

Согласно вашей логике, вложенный объект будет иметь экземпляр ObjectA, когда поле ObjectA (скажем, field2) встречается первым. Когда мы получаем следующее поле ObjectB (скажем, поле1), мы проверяем, является ли вложенный объект нулевым, и поскольку он не равен нулю, мы don' не создавать новый экземпляр для ObjectB. Из-за этого мы в конечном итоге устанавливаем значение поля ObjectB (field1) в ObjectA в следующей строке- nestedProp.getWriteMethod().invoke(nestedObject, value); Это приводит к ошибке - java.lang.IllegalArgumentException: объект не является экземпляром объявления класса


person coder87    schedule 19.03.2017    source источник


Ответы (2)


вам нужно объявить Object nestedObject=null; вне цикла, а затем создать экземпляр только один раз, проверив, что это null, как показано ниже:

if(nestedObject == null) {
    nestedObject  = classType.newInstance();
}
person developer    schedule 19.03.2017
comment
Я объявил это так же вне цикла. Пожалуйста, смотрите мое последнее редактирование. Он все еще не работает, так как произойдет сбой, если тип последнего итерируемого объекта отличается от типа текущего объекта в следующих строках -nestedProp.getWriteMethod().invoke(nestedObject, value); Здесь 'nestedObject' будет содержать тип последнего итерированного объекта. - person coder87; 19.03.2017
comment
где if чек? Я не мог найти это в вашем коде? - person developer; 19.03.2017
comment
Я протестировал его с условием, которое вы упомянули, а также с аналогичной логикой (которая закомментирована) до этого. Но это не сработало по причине, которую я упомянул в своем последнем комментарии. первый параметр метода вызова. - person coder87; 19.03.2017
comment
Чтобы было ясно, он может иметь ObjectB ObjectC (как вложенный в тот же класс вместе с ObjectA). В этом случае, согласно вашей логике, он также может иметь ObjectB или C в качестве последнего итерированного вложенного объекта, и мы пытаемся установить для него поле ObjectA неправильно что приводит к ошибке. - person coder87; 19.03.2017

Я мог заставить его работать после добавления следующих строк кода:

Object nestedObject = prop.getReadMethod().invoke(sourceObject);                                            
if(nestedObject == null){
        nestedObject  = classType.newInstance();    
}
person coder87    schedule 20.03.2017