DEV Community

saif ali
saif ali

Posted on

Java Annotations.

People Using Spring Framework in Java know how cool the annotations are, even I got surprised when I used the annotation for the first time. I'm not saying that only spring has annotations, Java itself has a lot of Annotation and that work so good and reduce a lot of codes.

When I was started to determine writing at least one annotation I thought the annotation will be capable of doing a lot of things without using any additional Methods, in fact, I was wrong.

If you want to write an annotation you need one Annotation and at least one method to facilitate the annotation,

The following example will show how easily you can create an annotation to Map fields from your Models to DTOs easily without having Setters or Constructors.

https://github.com/saifali40/mapper

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldMapper {
    public String field();
}

This is the annotation I wrote for my demo project, where it will Run on the Runtime for the fields you can try other targets and retention policies as well, for my requirement I need the retention as runtime and target as the field.

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import in.saifali.mapper.annotations.FieldMapper;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class Processor {
    Gson gson = new Gson();
    Map<Object, Object> dtoMap = new HashMap<>();
    Map<Object, Object> objectMap = new HashMap<>();
    public <T> T map(Class<T> t, Object object) {
        try {
            T returnClass = t.getDeclaredConstructor().newInstance();
            for (Field field : returnClass.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                if (field.isAnnotationPresent(FieldMapper.class)) {
                    dtoMap.put(field.getName(), field.getAnnotation(FieldMapper.class).field());
                }else{
                    dtoMap.put(field.getName(), field.getName());
                }
            }
            objectMap = gson.fromJson(gson.toJson(object), new TypeToken<HashMap<Object, Object>>() {
            }.getType());
            dtoMap.forEach((x, y) -> dtoMap.put(x, objectMap.get(y)));
            String json = gson.toJson(dtoMap);
            return gson.fromJson(json, t);
        } catch (Exception e) {
            throw new IllegalArgumentException();
        }
    }

}

As the retention is Runtime I can use the Java reflection API and getting each field with annotation @FieldMapper and mapping to respective fields.

From the above GitHub repository, you find the test cases and understand how to use the above annotation easily.

Note: I'm not good at writing.

Top comments (0)