我想编写一个方法来检查给定对象是否包含空值字段。我写的内容很好但是原始类型会出现问题。
public static <T> List<String> checkIfNullsInObject(T ob) {
List<String> fieldsAsNull = new LinkedList<>();
for (Field f : ob.getClass().getDeclaredFields()) {
f.setAccessible(true);
try {
if (Objects.isNull(f.get(ob))) {
fieldsAsNull.add(f.getName());
}
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
}
}
return fieldsAsNull;
}
所以,例如。
班级狗:
public class Dog {
private String name;
private int age;
private String owner;
///set get
}
给定对象:
Dog dog = new Dog();
// dog.setAge(44);
// dog.setName("Maniek");
// dog.setOwner("AZE");
该方法应该返回&#34;年龄,名称,所有者&#34;,但它只返回最后一个。我知道int被设置为0,因此它不被认为是null因为原始类型而不是对null的引用。
关于Field.get(Object o)方法的 java doc 说:
返回指定对象上此Field表示的字段的值。如果对象具有基本类型,则该值自动包装在对象中。
如果它被包裹到对象我希望它返回null,而不是零我在这里缺少什么?是否在中间的某个地方再次打开?
/////////////////////////////////////////////// //////
我知道将类型更改为Wrapper类可以完成这项工作,但是我不确定是否因为添加另一个类而改变另一个类是很好的做法因此我决定这样做:< / p>
public static <T> void checkIfNullsInObject(T ob) throws DataInputException {
try {
for (Field f : ob.getClass().getDeclaredFields()) {
f.setAccessible(true);
if (Objects.isNull(f.get(ob)) || checkForZeroPrimitives(ob, f))
throw new DataInputException("Can not update entity with field \""
+ f.getName() + "\" set to: " + f.get(ob));
}
} catch (IllegalArgumentException |IllegalAccessException e) {
e.getMessage();
e.printStackTrace();
}
}
private static <T> boolean checkForZeroPrimitives(T ob, Field field) throws IllegalArgumentException, IllegalAccessException {
if (field.getType().getName().equals("int") && field.getInt(ob) == 0)
return true;
if (field.getType().getName().equals("double") && field.getDouble(ob) == 0.0)
return true;
if (field.getType().getName().equals("float") && field.getFloat(ob) == 0)
return true;
if (field.getType().getName().equals("long") && field.getLong(ob) == 0)
return true;
if (field.getType().getName().equals("short") && field.getShort(ob) == 0)
return true;
if (field.getType().getName().equals("byte") && field.getByte(ob) == 0)
return true;
if (field.getType().getName().equals("char") && field.getChar(ob)=='\u0000')
return true;
return false;
}
稍后我打算改进-if阶梯。
答案 0 :(得分:3)
那是因为它用Object包裹了原语,而不是相反。这意味着age
中的dog
为0,那么你得到的值就是整数的包装。因此Integer包含0(未设置时,int自动具有值0)。
如果您希望age
能够为null,则必须使用包装对象(Integer
)而不是原语(int
)。
答案 1 :(得分:1)
您可以使用 {primitive type} .TYPE 检查字段中的某些原始数据类型,例如long RegisterRoutes
,其他人也一样。
答案 2 :(得分:1)
如果您使用以下原始类型的包装器,您的代码将起作用:
public class Dog {
private String name;
private Integer age;
private String owner;
}
答案 3 :(得分:0)
这是因为你声明它是原始的并且它的(int)默认值是零。如果你想在那种情况下处理它,那么在你自己的方法中处理它。
Objects.isNull(f.get(ob)) || (f.getType().getName().equals("int") && ((Integer)f.get(ob)).intValue() == 0)
就像这样,即使任何int字段被赋值为zero.eg,你也能得到。年龄(此字段永远不能为零)
如果你在这种情况下使用Integer,你不需要做任何事情。
private Integer age;
private int number;
private String role = "";
private void testNull(){
Test ob = new Test();
List<String> fieldsAsNull = new LinkedList<>();
for (Field f : ob.getClass().getDeclaredFields()) {
f.setAccessible(true);
try {
if (Objects.isNull(f.get(ob)) || (f.getType().getName().equals("int") && ((Integer)f.get(ob)).intValue() == 0)) {
fieldsAsNull.add(f.getName());
}
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
}
}
System.out.println(fieldsAsNull);
}
输出:[年龄,数字]