简体   繁体   中英

Should I avoid using annotations?

In my project I'm loading configuration from a json file (using gson) and as you probably know, missing fields will be populate with an empty string.

Some of the fields are mandatory and other must be greater then X, and I want to validate it.

The simple (and ugly) way is to use if condition for each property, like:

if (StringUtils.isEmpty(sftpConfiguration.getHostName)) {
   logger.error (“hostName property is mandatory”);
  // etc.
}

but, I have more than one field and more and more properties will added in the future, therefore I built two annotations, called NorNullEmpty and GreaterThen (with value property) and I run throw the fields like this:

public static boolean validateWithAnnotation(Object object) throws IllegalAccessException {
    boolean result = true;
    Field[] classFields = object.getClass().getDeclaredFields();

    for (Field field : classFields) {
        if (field.getAnnotation(NorNullEmpty.class) != null) {
            if (field.getType() == String.class) {
                field.setAccessible(true);
                String value = (String) field.get(object);
                if (StringUtils.isEmpty(value)) {
                    result = false;
                    logger.error("Property {} is mandatory but null or an empty.", field.getName());
                }
                field.setAccessible(false);
            } else {
                logger.warn("@NorNullEmpty annotation is working on String type only.");
            }
        } else if (field.getAnnotation(GreaterThan.class) != null) {
            Class<?> fieldType = field.getType();
            if (fieldType == long.class || fieldType == Long.class) {
                field.setAccessible(true);
                Long val = field.getLong(object);
                if (val <= field.getAnnotation(GreaterThan.class).value()) {
                    result = false;
                    logger.error("Property {} value is {} and it must be greater than {}.", field.getName(), val, field.getAnnotation(GreaterThan.class).value());
                }
                field.setAccessible(false);
            }
        }
    }

    return result;
}

When I did a code review with a collage he very afraid from the annotations use, “it's very risky and very expensive cost”..

I'll be glad to know what you think, should I use a simple-stupid if for each field? continue with the reflection? or I should validate the fields using other way?

Note: NOT using Spring / Hibernate.

First of all you're trying to re-invent the wheel. There is a project called Hibernate Validator which is an implementation of the bean validation reference specification.

Here is an example from their landing page:

public class Car {

   @NotNull
   private String manufacturer;

   @NotNull
   @Size(min = 2, max = 14)
   private String licensePlate;

   @Min(2)
   private int seatCount;

   // ...
}

So you define validations and run the engine, it will perform all the checks and return Errors if there are any. You can even roll your own validations which makes it extensible.

One side-note - this project has nothing common with Hibernate (a well known in the java world ORM mapping tool).

This project also integrates with spring MVC if you need something like that.

Anyway, it does use the annotation approach and it indeed has some performance penalty. However it all depends on what kind of data do you have, for example its still much faster than doing network calls, so if your project does something like that, probably the additional cost will be negligible.

Reflection is not that slow as it used to be in the first Java versions, but bottom line you should try and see yourself whether it fits your needs. Otherwise I can only speculate.

Here you can find a tutorial about this topic, should be relevant

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM