Java Development Tips: Enums, RESTful API Standards, Bean Conversion, Stream Operations, and Null/Assertion Handling
This article shares practical Java backend development techniques, covering safe enum usage, RESTful API design guidelines, generic bean conversion via JSON, effective Stream API patterns, and comprehensive null‑checking and assertion strategies to improve code reliability and maintainability.
Preface
The author, a Java developer with three years of experience in SaaS and PaaS projects, shares accumulated tricks and experiences such as bug handling, daily development, and team coding standards.
1. Enum Annotations
Common pitfalls when using enums include accidental modification of enum values and unclear constructor or member method definitions. The author provides a clear example using Lombok annotations to make enum fields immutable and generate constructors.
@Getter // only getter, no setter
@RequiredArgsConstructor // generate constructor for enum fields
public enum ProjectStatusEnum {
SURVEY("已调研"),
APPROVAL("已立项"),
PROGRESSING("进行中"),
COMPLETED("已完成");
private final String name;
}A bug caused by calling a setter on an enum value is described.
2. RESTful API Guidelines
The author recommends avoiding Swagger/Knife4j due to invasiveness and security concerns, and suggests using smart-doc with standard Javadoc comments.
Request Methods and Parameters Prefer only GET and POST in controllers; use @GetMapping with @RequestParam or @PathVariable , limiting parameters to five. Use @PostMapping with @RequestBody and DTOs. Add @RequestHeader or @Valid for header and validation.
Unified Response Return a standard response body containing code, message, and data, encapsulated in VO objects with unified exception handling.
Example controller:
/**
* Test API
*/
@RestController
@RequestMapping("/study")
public class StudyController {
@Resource
private StudyService studyService;
/**
* Add new record
*/
@PostMapping("/add")
public Response
addStudy(@RequestBody @Valid StudyDTO studyDTO) {
return ResultUtils.success(studyService.addStudy(studyDTO));
}
/**
* List records (no pagination)
*/
@GetMapping("/list")
public Response
> getList(@RequestParam("id") String id) {
return ResultUtils.success(studyService.getList(id));
}
}3. Bean Property Conversion
Using @Data or @Builder works for small objects, but for many fields a generic JSON‑based conversion is recommended. Define a base class CommonBean with a generic method, let all VO/Entity/DTO classes extend it, and invoke the method for conversion.
4. Stream API Usage
Common Stream methods like map() and collect() are highlighted. The author shows filtering, sorting, and mapping with a MySQL query result, and warns against performing database‑level operations in streams when they can be done in the query.
@Override
public List
getList(String id) {
List
resultList = this.list(new LambdaQueryWrapper
()
.eq(Study::getIsDelete, NumberUtils.INTEGER_ZERO))
.stream()
.filter(e -> Constants.USER_ROLE_USER.equals(e.getUserRole()))
.sorted(Comparator.comparing(Study::getAge).reversed())
.map(e -> e.copyProperties(StudyVO.class))
.collect(Collectors.toList());
return Optional.of(resultList).orElse(null);
}Additional example demonstrates anyMatch() to check for valid articles before mapping.
public List
testStreamAnyMatch() {
List
articleList = this.list(new LambdaQueryWrapper
()
.eq(Article::getIsDelete, NumberUtils.INTEGER_ZERO));
if (CollectionUtils.isNotEmpty(articleList)) {
boolean flag = articleList.parallelStream()
.anyMatch(e -> Objects.nonNull(e) && Objects.nonNull(e.getContent()) && StringUtils.isNotBlank(e.getTitle()));
if (flag) {
return articleList.parallelStream()
.map(e -> e.copyProperties(ArticleVO.class))
.collect(Collectors.toList());
}
}
return new ArrayList<>();
}5. Null Checks and Assertions
5.1 Null Checks
The author lists three typical scenarios requiring null checks: object reference usage, external data retrieval, and collection element operations. Recommended utilities include Objects.nonNull() for objects, CollectionUtils.isNotEmpty() for collections, Map.isEmpty() / containsKey() for maps, and StringUtils.isNotBlank() for strings.
@Test
public void testNullMethod(){
Study study = null;
String userName = study.getUserName(); // NPE
log.info("User name: {}", userName);
} @Override
public StudyVO detail(String id) {
List
resultList = this.list(new LambdaQueryWrapper
()
.eq(Study::getIsDelete, NumberUtils.INTEGER_ZERO)
.orderByDesc(Study::getAge));
if (CollectionUtils.isNotEmpty(resultList)) {
return resultList.get(NumberUtils.INTEGER_ZERO).copyProperties(StudyVO.class);
}
return new StudyVO();
}5.2 Assertions
Assertions are useful when business logic must abort on missing data. Examples include Assert.notNull() , Assert.isTrue() , Assert.hasText() , and collection assertions.
if (Objects.nonNull(obj)) {
throw new BusinessException("obj error");
}
// becomes
Assert.notNull(obj, "obj error"); // Boolean assertion
Assert.isTrue(condition, "Condition must be true");
// Object assertion
Assert.notNull(object, "Object cannot be null");
// String assertion
Assert.hasText(text, "String must have content");
// Collection/Map assertion
Assert.notEmpty(map, "Map cannot be empty");
Assert.notEmpty(collection, "Collection cannot be empty");Conclusion
The article serves as the introductory part of a series, focusing on basic Java development tips. Future posts will cover online bug handling, cache usage, asynchronous processing, and decoupling techniques.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.