table of Contents
A comment
Annotations are a very important part of Java. We use them all the time, especially when developing with the Spring framework. But how to customize an annotation, or how does an annotation take effect, and what is its working principle? Next, let’s make a comment together
What is the annotation
Annotation is a concept introduced in Java 1.5 and belongs to a type. Annotations provide a series of data to modify the program code (classes, methods, fields), but the annotation is not part of the modified code, that is, it has no direct impact on the operation of the code, and the compiler determines which operations to perform
Annotation life cycle
There are three strategies for the life cycle of annotations, which are defined in the RetentionPolicy enumeration
- SOURCE: valid in the source file and discarded by the compiler
- CLASS: valid in the bytecode file generated by the compiler, but will be discarded by the JVM that processes the class file at runtime
- RUNTIME: Valid at runtime. This is also the most commonly used strategy in the annotation life cycle, which allows continuous access to annotations through reflection, and executes the corresponding code according to the definition of the annotation
The goal of annotation modification
The goal of the annotation defines which level of Java code the annotation will be applied to. Some annotations are only applicable to methods.
The types of annotations in 11 are defined in ElementType
- TYPR: used for classes, interfaces, annotations, enumerations
- FIELD: Used for fields (member variables of the class), or enum constants
- METHOD: Used for methods
- PARAMETER: used for parameters of ordinary methods or construction methods
- CONSTRUCTOR: used to construct the method
- LOCAL_VARIABLE: used for variables
- ANNOTATION_TYPE: used for annotation
- PACKAGE: used for packages
- TYPE_PARAMETER: used for generic parameters
- TYPE_USE: used to declare the type in the statement, generic or cast statement
- MODULE: for modules
Start commenting
Let’s mark a field’s annotation to mark whether the object should contain this field when it is serialized into JSON
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JsonField {
public String value() default "";
}
-
Explanation:
- The life cycle of JsonField annotation is RUNTIME, which is valid at runtime
- The goal of JsonField annotation modification is FIELD, which is for the field
- @Interface keyword is needed to create annotation
- JsonField annotation has only one parameter, the name is value, the type is String, and the default value is an empty string
The parameter name is value, allowing the user of the annotation to provide a parameter without specifying a name. That is, we can use @JsonField (value="塚狐") on a field, or omit value= to become @JsonField ("塚狐")
- default "" allows us to directly use @JsonField on a field without specifying the name and value of the parameter
Use annotations
Create a class, containing three fields: age, name, address, the last two are required serialized fields
public class People {
private int age ;
@JsonField("writeName")
private String name;
@JsonField
private String address;
public People(int age,String name,String address){
this.age=age;
this.name=name;
this.address=address;
}
@Override
public String toString() {
return "People{" +
"age=" + age +
", name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
among them:
- The @JsonField annotation on the name provides the displayed string value
- The @JsonField annotation on address uses the default value
Next we write the serialization class JsonSerializer:
public class JsonSerializer {
public static String serialize(Object object) throws IllegalAccessException {
Class<?> objectClass = object.getClass();
Map<String, String> jsonElements = new HashMap<>();
for (Field field : objectClass.getDeclaredFields()) {
field.setAccessible(true);
if (field.isAnnotationPresent(JsonField.class)) {
jsonElements.put(getSerializedKey(field), (String) field.get(object));
}
}
return toJsonString(jsonElements);
}
private static String getSerializedKey(Field field) {
String annotationValue = field.getAnnotation(JsonField.class).value();
if (annotationValue.isEmpty()) {
return field.getName();
} else {
return annotationValue;
}
}
private static String toJsonString(Map<String, String> jsonMap) {
String elementsString = jsonMap.entrySet()
.stream()
.map(entry -> "\"" + entry.getKey() + "\":\"" + entry.getValue() + "\"")
.collect(Collectors.joining(","));
return "{" + elementsString + "}";
}
}
Let's take a look at their respective meanings and functions:
serialize()
The method is used to serialize an object, and it receives a parameter of type Object.objectClass.getDeclaredFields()
Get all the fields declared by the object by reflection, and then traverse the for loop. In a for loop, first byfield.setAccessible(true)
the reflecting object accessibility set to true, for the sequence of use (without this step, then, private field can not be obtained, throws IllegalAccessException exception); again byisAnnotationPresent()
determining whether the field decoratedJsonField
annotation, and if so, calls thegetSerializedKey()
method, and thus obtain the value field indicates the object, and placed in jsonElements.getSerializedKey()
The method is used to get the value of the annotation on the field. If the value of the annotation is empty, the field name is returned.toJsonString()
The method returns the formatted JSON string with the help of Stream.
Test notes
public class JsonFileTest {
public static void main(String[] args) throws IllegalAccessException{
People cmower = new People(18,"冢狐","中国");
System.out.println(JsonSerializer.serialize(cmower));
}
}
- result:
{"WriteName":"Mound Fox","address":"China"}
- analysis
- First, the age field is not annotated by @JsonField so it is not serialized
- The name modifies the @JsonField annotation and shows that the string writerName is specified, so it becomes writeName after serialization
- The address field is decorated with the @JsonField annotation, but the specified value is not displayed, so it is still address after serialization
At last
- If you feel that you are rewarded after reading, I hope to give me a thumbs up. This will be my biggest motivation for updating. Thank you for your support.
- Welcome everyone to pay attention to my official account [java Toka Fox], focus on the basic knowledge of java and computer, and ensure that you will get something after reading it. If you don’t believe me, hit me
- If you have different opinions or suggestions after reading, welcome to comment and share. Thank you for your support and love.