java屏蔽了指针,但是空指针是个例外。java8 加入了Optional,可以更优雅的避免空指针异常。举例说明
package com.ioufev.mqtt.entities;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
/**
* @Auther: Zg
* @Date: 2023/1/4 - 01 - 04 - 22:27
* @Description: com.ioufev.mqtt.entities
* @version: 1.0
*/
@Data
@Builder
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private Integer id;
private String name;
private String sex;
private Date date;
}
方式1,传统方法,并不能检测出空指针:
@SneakyThrows
@Test
void nullPointerExTest1() {
Student stuNull = null;
Student stu = Student.builder()
.id(1)
.date(new Timestamp(new Date().getTime()))
.name("antetokounmpo")
.sex("male")
.build();
//方式一:不能检测出空指针:
Map<String, Object> map = new HashMap<>();
Field[] fields = stuNull.getClass().getDeclaredFields();
for (Field f : Arrays.asList(fields)
) {
f.setAccessible(true);
map.put(f.getName(),f.get(stuNull));
}
for (Map.Entry<String,Object> entry : map.entrySet()
) {
log.info(entry.getKey() +"---->"+entry.getValue());
}
}
方式2:虽然也出现了空指针,但是直接跳转到了 new Field[]{} 避免了空指针
@SneakyThrows
@Test
void nullPointerExTest2(){
Student stuNull = null;
Student stu = Student.builder()
.id(1)
.date(new Timestamp(new Date().getTime()))
.name("antetokounmpo")
.sex("male")
.build();
//方式二:能检测出空指针:
Map<String, Object> map = new HashMap<>();
Field[] fields = Optional.ofNullable(stuNull)
.map(x -> x.getClass())
.map(y -> y.getDeclaredFields())
.orElse(new Field[]{});
for (Field f : Arrays.asList(fields)
) {
f.setAccessible(true);
map.put(f.getName(),f.get(stuNull));
}
for (Map.Entry<String,Object> entry : map.entrySet()
) {
log.info(entry.getKey() +"---->"+entry.getValue());
}
}
正确的写法:
@Test
void nullPointerExTest3(){
Student stuNull = null;
Student student = new Student();
Student stu = Student.builder()
.id(1)
.date(new Timestamp(new Date().getTime()))
.name("antetokounmpo")
.sex("male")
.build();
//方式二:能检测出空指针:
Map<String, Object> map = new HashMap<>();
Field[] fields = Optional.ofNullable(student)
.map(Student::getClass)
.map(Class::getDeclaredFields)
.orElse(new Field[]{});
Arrays.asList(fields).forEach(field -> {
field.setAccessible(true);
try {
map.put(field.getName(),field.get(stu));
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
});
map.entrySet().forEach(entry->{
log.info(entry.getKey()+"---->"+ entry.getValue());
});
}
C# 中 有更优雅的写法:
EmployeeInfo employeeInfo = new EmployeeInfo();
string s = (employeeInfo?.EmpPYNo);
//判断employeeInfo 是否为null。 如果为null则不执行后面的方法,属性,直接返回null
string ss = employeeInfo.Phone ?? employeeInfo.EmpName;
//如果employeeInfo.Phone 存在则返回左边,否则右边