44 java exception-handling nullpointerexception
我需要检查一些值是否为null.如果它不为null,那么只需将一些变量设置为true即可.这里没有其他声明.我得到了太多像这样的条件检查.
有没有办法处理这个空检查而不检查所有方法返回值?
if(country != null && country.getCity() != null && country.getCity().getSchool() != null && country.getCity().getSchool().getStudent() != null .....) {
isValid = true;
}
Run Code Online (Sandbox Code Playgroud)
我想直接检查变量并忽略NullpointerException.这是一个好习惯吗?
try{
if(country.getCity().getSchool().getStudent().getInfo().... != null)
} catch(NullPointerException ex){
//dont do anything.
}
Run Code Online (Sandbox Code Playgroud)
khe*_*ood 67
不,在Java中捕获NPE而不是对引用进行空值检查通常不是一种好习惯.
Optional
如果你愿意,你可以使用这种东西:
if (Optional.ofNullable(country)
.map(Country::getCity)
.map(City::getSchool)
.map(School::getStudent)
.isPresent()) {
isValid = true;
}
Run Code Online (Sandbox Code Playgroud)
或者干脆
boolean isValid = Optional.ofNullable(country)
.map(Country::getCity)
.map(City::getSchool)
.map(School::getStudent)
.isPresent();
Run Code Online (Sandbox Code Playgroud)
如果那是isValid
应该检查的全部.
use*_*er7 16
您可以Optional
在这里使用,但它会在每一步创建一个Optional对象.
boolean isValid = Optional.ofNullable(country)
.map(country -> country.getCity()) //Or use method reference Country::getCity
.map(city -> city.getSchool())
.map(school -> school.getStudent())
.map(student -> true)
.orElse(false);
//OR
boolean isValid = Optional.ofNullable(country)
.map(..)
....
.isPresent();
Run Code Online (Sandbox Code Playgroud)
面向对象的方法是将isValid方法放在Country和其他类中.它不会减少空检查的数量,但每个方法只有一个,您不会重复它们.
public boolean isValid() {
return city != null && city.isValid();
}
Run Code Online (Sandbox Code Playgroud)
这假设在您的国家/地区使用的地方验证是相同的,但通常就是这种情况.如果没有,该方法应命名为hasStudent(),但这不太通用,您可能会在Country中复制整个School界面.例如,在另一个地方,您可能需要hasTeacher()或hasCourse().
另一种方法是使用null对象:
public class Country {
public static final Country NO_COUNTRY = new Country();
private City city = City.NO_CITY;
// etc.
}
Run Code Online (Sandbox Code Playgroud)
我不确定这种情况是否更可取(严格来说你需要一个子类来覆盖所有修改方法),Java 8的方法是在其他答案中使用Optional作为方法,但我建议接受它更全面:
private Optional<City> city = Optional.ofNullable(city);
public Optional<City> getCity() {
return city;
}
Run Code Online (Sandbox Code Playgroud)
对于null对象和Nullable,只有在始终使用它们而不是null时才会工作(注意字段初始化),否则您仍然需要空检查.所以这个选项避免了null,但你的代码变得更加冗长,以减少其他地方的空值检查.
当然,正确的设计可能是尽可能使用集合(而不是可选).一个国家有一套城市,城市有一套学校,有一组学生等.
作为其他精细用法的替代方法Optional
,我们也可以使用带有Supplier<Object>
var-args作为参数的实用程序方法.
这是有道理的,因为我们在要检查的对象中没有很多嵌套级别,但需要检查许多字段.
此外,它可以很容易地被修改以记录/处理null
检测到的东西.
boolean isValid = isValid(() -> address, // first level
() -> address.getCity(), // second level
() -> address.getCountry(),// second level
() -> address.getStreet(), // second level
() -> address.getZip(), // second level
() -> address.getCountry() // third level
.getISO()
@SafeVarargs
public static boolean isValid(Supplier<Object>... suppliers) {
for (Supplier<Object> supplier : suppliers) {
if (Objects.isNull(supplier.get())) {
// log, handle specific thing if required
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
假设你想添加一些痕迹,你可以写:
boolean isValid = isValid( Arrays.asList("address", "city", "country",
"street", "zip", "Country ISO"),
() -> address, // first level
() -> address.getCity(), // second level
() -> address.getCountry(),// second level
() -> address.getStreet(), // second level
() -> address.getZip(), // second level
() -> address.getCountry() // third level
.getISO()
);
@SafeVarargs
public static boolean isValid(List<String> fieldNames, Supplier<Object>... suppliers) {
if (fieldNames.size() != suppliers.length){
throw new IllegalArgumentException("...");
}
for (int i = 0; i < suppliers.length; i++) {
if (Objects.isNull(suppliers.get(i).get())) {
LOGGER.info( fieldNames.get(i) + " is null");
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6435 次 |
最近记录: |