Java 如何跳过对象中的空项而不写入多个if语句或try块?
我正在使用一些代码,其中用户发送一个对象,该对象最多可以有100个值。(让我们以汽车为例) 汽车对象可以有名称、里程、vin、颜色等内容。。。但假设我只设置颜色,然后传递对象 在我的方法中: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
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)
注意,使用此方法会对类应用附加限制(