Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何跳过对象中的空项而不写入多个if语句或try块?_Java_Object_If Statement_Try Catch_Getter Setter - Fatal编程技术网

Java 如何跳过对象中的空项而不写入多个if语句或try块?

Java 如何跳过对象中的空项而不写入多个if语句或try块?,java,object,if-statement,try-catch,getter-setter,Java,Object,If Statement,Try Catch,Getter Setter,我正在使用一些代码,其中用户发送一个对象,该对象最多可以有100个值。(让我们以汽车为例) 汽车对象可以有名称、里程、vin、颜色等内容。。。但假设我只设置颜色,然后传递对象 在我的方法中: public void updateDatabasePrep(Car carObject){ NewObject myObject = newObject(); //Initialized, but empty String x1 = carObject.getMilage(); S

我正在使用一些代码,其中用户发送一个对象,该对象最多可以有100个值。(让我们以汽车为例)

汽车对象可以有名称、里程、vin、颜色等内容。。。但假设我只设置颜色,然后传递对象

在我的方法中:

public void updateDatabasePrep(Car carObject){
    NewObject myObject = newObject(); //Initialized, but empty
    String x1 = carObject.getMilage();
    String x2 = carObject.getColor();
    String x3 = carObject.getName();
    //These will hold null values no problem

    //Once the rest of the data has been collected:

    //These, however, will error out when I try to set the null values.
    myObject.setMilage(x1);
    myObject.setColor(x2);
    myObject.setName(x3);
}
它使用访问器方法从传递的对象中提取数据,然后尝试设置所述值。在上述情况下,由于milage和name为null,它将抛出null指针错误;只有颜色不是

我的目标是仅使用已设置的值更新数据库。在这种情况下,我可以为每一条语句编写大量的if/else或try/catch语句,这是可行的,但我宁愿不这样做

在Java中有没有一种更短的方法来实现这一点?是否有一种方法,您只能在数据不为null时设置数据,而不是if/else、try/catch、遍历每个setter方法并告诉它跳过null值

编辑: 只是澄清一下,当它试图设置空值时,会抛出Nullpointerexception。即

myObject.setMilage(x1);

因为我们问的人

我不确定您是如何使用过程或准备好的调用更新数据库的。然而,下面可能会对您有所帮助

您可以获得具有
null
值的字段列表-

public List<String> getNullFields(Car car) {
    Field[] fields = car.getClass().getDeclaredFields();
    List<String> result = new ArrayList<String>();
    for (Field field : fields) {
        try {
            field.setAccessible(true);
            Object value = field.get(car);
            if(value == null) {
                result.add(field.getName());
            }
        } catch (IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return result;
}
公共列表getNullFields(汽车){
Field[]fields=car.getClass().getDeclaredFields();
列表结果=新建ArrayList();
用于(字段:字段){
试一试{
字段。setAccessible(true);
对象值=field.get(汽车);
如果(值==null){
add(field.getName());
}
}捕获(IllegalArgumentException | IllegalAccessException e){
e、 printStackTrace();
}
}
返回结果;
}
或者,您也可以使用类似的方法获得非空值的字段(以及精确值)


然后,您可以基于此结果动态构造准备好的语句。祝你好运

我不确定您是如何使用过程或准备好的调用更新数据库的。然而,下面可能会对您有所帮助

您可以获得具有
null
值的字段列表-

public List<String> getNullFields(Car car) {
    Field[] fields = car.getClass().getDeclaredFields();
    List<String> result = new ArrayList<String>();
    for (Field field : fields) {
        try {
            field.setAccessible(true);
            Object value = field.get(car);
            if(value == null) {
                result.add(field.getName());
            }
        } catch (IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return result;
}
公共列表getNullFields(汽车){
Field[]fields=car.getClass().getDeclaredFields();
列表结果=新建ArrayList();
用于(字段:字段){
试一试{
字段。setAccessible(true);
对象值=field.get(汽车);
如果(值==null){
add(field.getName());
}
}捕获(IllegalArgumentException | IllegalAccessException e){
e、 printStackTrace();
}
}
返回结果;
}
或者,您也可以使用类似的方法获得非空值的字段(以及精确值)


然后,您可以基于此结果动态构造准备好的语句。祝你好运

假设
myObject
总是相同的类型,您可以使用反射来进行映射阶段,将getter和setter方法放在hashmap中,如下所示:

    private HashMap<Method, Method> methodMap;

    private void doReflection()
    {
      Method[] carMethods = carObject.getClass().getDeclaredMethods();
      ArrayList<Method> getters = new ArrayList<>();

      for(int i = 0; i < carMethods.size(); i++)
        if(carMethods[i].getName().startsWith("get")) getters.add(carMethods[i]);

      methodMap = new HashMap<>();
      for(Method m : getters)
      {
        String fieldName = m.getName().substring(3);
        Method setter = myObject.class.getMethod("set" + fieldName, m.getParameterTypes());

        if(setter != null) methodMap.put(m, setter);
      }
    }
私有HashMap methodMap;
私有void doReflection()
{
方法[]carMethods=carObject.getClass().getDeclaredMethods();
ArrayList getters=新的ArrayList();
对于(int i=0;i
现在,您可以迭代HashMap来执行如下分配:

for(MapEntry<Method, Method> entry : methodMap.entrySet())
{
  Method getter = entry.getKey();
  Method setter = entry.getValue();

  Object o = getter.invoke(carObject, null);
  if(o != null) setter.invoke(myObject, getter.invoke(carObject, null));
}
for(映射条目:methodMap.entrySet())
{
方法getter=entry.getKey();
方法setter=entry.getValue();
对象o=getter.invoke(carObject,null);
如果(o!=null)setter.invoke(myObject,getter.invoke(carObject,null));
}

假设
myObject
总是相同的类型,您可以使用反射来进行映射阶段,将getter和setter方法放在hashmap中,如下所示:

    private HashMap<Method, Method> methodMap;

    private void doReflection()
    {
      Method[] carMethods = carObject.getClass().getDeclaredMethods();
      ArrayList<Method> getters = new ArrayList<>();

      for(int i = 0; i < carMethods.size(); i++)
        if(carMethods[i].getName().startsWith("get")) getters.add(carMethods[i]);

      methodMap = new HashMap<>();
      for(Method m : getters)
      {
        String fieldName = m.getName().substring(3);
        Method setter = myObject.class.getMethod("set" + fieldName, m.getParameterTypes());

        if(setter != null) methodMap.put(m, setter);
      }
    }
私有HashMap methodMap;
私有void doReflection()
{
方法[]carMethods=carObject.getClass().getDeclaredMethods();
ArrayList getters=新的ArrayList();
对于(int i=0;i
现在,您可以迭代HashMap来执行如下分配:

for(MapEntry<Method, Method> entry : methodMap.entrySet())
{
  Method getter = entry.getKey();
  Method setter = entry.getValue();

  Object o = getter.invoke(carObject, null);
  if(o != null) setter.invoke(myObject, getter.invoke(carObject, null));
}
for(映射条目:methodMap.entrySet())
{
方法getter=entry.getKey();
方法setter=entry.getValue();
对象o=getter.invoke(carObject,null);
如果(o!=null)setter.invoke(myObject,getter.invoke(carObject,null));
}

反思是你的答案。您也可以尝试使用一些库,使其更加方便(例如)

因此,您可以执行以下操作:

private void copyIfSpecified(final Car from, final NewObject to, final String propName)
        throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    final Object value = PropertyUtils.getSimpleProperty(from, propName);
    if (value != null) {
        PropertyUtils.setSimpleProperty(to, propName, value);
    }
}
并从您的方法调用它:

public void updateDatabasePrep(Car carObject){
    NewObject myObject = new NewObject(); //Initialized, but empty

    try {
        copyIfSpecified(carObject, myObject, "milage");
        copyIfSpecified(carObject, myObject, "color");
        copyIfSpecified(carObject, myObject, "name");
    } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
        throw new RuntimeException("Error while populating fields", ex);
    }
}
这样可以显式指定要复制的属性,但避免过多的if语句。如果您不必确保始终复制您想要的所有字段(例如,字段集是固定的,并且不会随时间而改变),您可以通过反射完成整个复制工作(即获取源对象的所有字段,并将非空值复制到目标对象的字段-请参阅
PropertyUtils.copyProperties(…)
implementation)

注意,使用此方法会对类应用附加限制(