The most elegant way would be using JSR 380 bean validation.
It is a set of tools, including useful common annotations, to define bean class metadata for constraint validation.
You don't need to read the full spec to get the gist of it :
You'd want to define a group class for this specific set of constraints
public interface MyCustomIsEmpty{}
Then annotate each relevant field with
@Max(value = 0, groups = { MyCustomIsEmpty.class })
@Min(value = 0, groups = { MyCustomIsEmpty.class })
making sure to use the javax.validation.constraints
annotation classes.
Now your actual isEmpty() would be as simple as getting the default validator and validating the current instance :
public boolean isEmpty() {
// Gets validator instance from factory
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
// Validates 'this' using only fields belonging to the MyCustomIsEmpty group
Set<ConstraintViolation<MyClass>> constraintViolations = validator.validate(this, MyCustomIsEmpty.class);
// there are lots of fancy things you could do but this covers your case
return constraintViolations.isEmpty();
}
You could simplify the equivalent of the two combined annotations into a single custom one for less verbosity. This is covered in the spec.