The article directories
- Introduction to the
- Definition and use of annotations
- Yuan notes
-
- @Retention
- @Documented
- @Target
- @Inherited
- @Repeatable
- Attributes of annotations
- Java preconfigured annotations
-
- @Deprecated
- @Override
- @SuppressWarnings
- @SafeVarargs
- @FunctionalInterface
- Annotations and reflections
-
- Annotations on a class
- Annotations on properties and methods
- Usage scenarios for annotations
- chestnuts
- Annotation Application Example
-
- JUnit
- ButterKnife
Introduction to the
Annotation is a very important knowledge in Java, beginners can understand Annotation: imagine code is alive, Annotation is a label attached to some living individual in the code. In a nutshell, a annotation is like a label
Because the common development is rare, I believe that many people will think that the status of annotations is not high. Annotations are a type, just like class and interface. It was introduced in Java SE 5.0
Definition and use of annotations
Annotations are defined by the @interface keyword
public @interface TestAnnotation {
}
Copy the code
It looks like an interface, but with an @ sign in front of it. The above code creates an annotation named TestAnnotaion
Now that you have created an annotation, what is the usage of the annotation
@TestAnnotation
public class Test {}Copy the code
To annotate the class with TestAnnotation, create a class Test and add @testannotation to the class definition
However, for annotations to work properly, a new concept needs to be introduced: meta-annotations
Yuan notes
A meta-comment is a comment that can be added to a comment, or a meta-comment is a basic comment that can be applied to other comments
Meta labels include @Retention, @documented, @target, @Inherited, and @REPEATable
@Retention
Retention Retention means Retention period. When @Retention is applied to a annotation, it explains the annotation’s lifetime
Its values are as follows:
- The retentionPolicy.source annotation is only retained at the SOURCE stage and is discarded and ignored when the compiler compiles
- The retentionPolicy.class annotation is only retained until compilation and is not loaded into the JVM
- Retentionpolicy.runtime annotations can be retained until the application is run, and they are loaded into the JVM, so they can be retrieved while the application is running
@Retention is the equivalent of stamping a label with a time stamp that specifies the period in which the label was posted
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
Copy the code
In the code above, we specified that the TestAnnotation notation can be accessed during the run cycle of the program, so its life cycle is very long
@Documented
As the name implies, this meta-annotation must be related to the document. It provides the ability to include elements from annotations into Javadoc
@Target
Target means Target, and @target specifies where the annotation should be used
By analogy, tags can be posted anywhere you want, but thanks to @target, they can only be posted to methods, classes, method parameters, and so on. At sign Target has the following values
- Elementtype. ANNOTATION_TYPE Annotates an annotation
- Elementtype. CONSTRUCTOR can be annotated to a CONSTRUCTOR
- Elementtype. FIELD can be used to annotate attributes
- Elementtype. LOCAL_VARIABLE can be used to annotate local variables
- ElementType.METHOD can annotate methods
- Elementtype. PACKAGE can annotate a PACKAGE
- Elementtype. PARAMETER can be used to annotate parameters within a method
- Elementtype. TYPE can annotate a TYPE, such as a class, interface, or enumeration
@Inherited
Inherited means Inherited, but it does not mean that the annotations themselves can be Inherited. It means that if a superclass is annotated by @Inherited annotations, then if its subclass is not applied by any annotations, it inherits the superclass’s annotations
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}
Copy the code
The Test annotation is annotated by @inherited, and when class A is annotated by Test, class B inherits FROM A, and class B has the Test annotation
@Repeatable
Repeatable means Repeatable
What annotations are used more than once? Usually the value of an annotation can be multiple at the same time
Take, for example, a person who is a programmer, a product manager, and a painter
@interface Persons {
Person[] value();
}
@Repeatable(Persons.class)
@interface Person{
String role default "";
}
@Person(role="artist")
@Person(role="coder")
@Person(role="PM")
public class SuperMan{}Copy the code
Notice the code above, @REPEATable annotates Person. The class in parentheses after @REPEATable is equivalent to a container annotation
What are container annotations? It’s a place to store other notes. It is a note in itself
Let’s look again at the relevant container annotations in the code
@interface Persons {
Person[] value();
}
Copy the code
As specified, it must have a value property in it. The property type is an array of annotations annotated by @REPEATable. Note that it is an array
If it’s hard to understand, you can understand it this way. Persons is a generic tag filled with Person tags of the same type but with different content. To label Persons as SuperMan is to label him as programmer, product manager and painter.
Person(role= “PM”), which assigns PM to the role attribute of the annotation
Attributes of annotations
Attributes of annotations are also called member variables. Annotations have only member variables and no methods. An annotation’s member variable is declared in the annotation definition as a method of invisible parameters, whose method name defines the name of the member variable, and whose return value defines the type of the member variable
- The following code defines the TestAnnotation annotation that has the ID and MSG attributes. When used, we should assign values to them
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
int id(a);
String msg(a);
}
Copy the code
This is done by enclosing the annotation in parentheses with the form value=””, separated from multiple attributes by a comma
@TestAnnotation(id=3,msg="hello annotation")
public class Test {}Copy the code
Note that the type of an attribute defined in an annotation must be the eight basic data types plus classes, interfaces, annotations, and their arrays
- Attributes in annotations can have default values, which need to be specified with the default key value. Such as
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
public int id(a) default- 1;
public String msg(a) default "Hi";
}
@TestAnnotation()
public class Test {}
Copy the code
The default value of the ID attribute in TestAnnotation is -1 and the default value of the MSG attribute is Hi. There is no need to assign the notation in parentheses following the @testannotation notation. This step can be omitted
- If an annotation contains only one attribute named value, the attribute value can be filled in parentheses when the annotation is applied
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Check {
String value(a);
}
Copy the code
The Check annotation only has the value attribute. So you can apply it this way
@Check("hi")
int a;
Copy the code
This has the same effect as the following
@Check(value="hi")
int a;
Copy the code
- Note also that if an annotation has no attributes, the parentheses can be omitted when the annotation is applied
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Perform {
}
@Perform
public void testMethod(a){}
Copy the code
Java preconfigured annotations
We learned about custom annotations above, but the Java language itself already provides several ready-made annotations
@Deprecated
This element is used to mark obsolete elements, which you might encounter in your daily development. When the compiler encounters this annotation at compile time, it will issue a reminder warning that the developer is calling an outdated element such as an outdated method, an outdated class, or an outdated member variable
Defines a Hero class that has two methods say() and speak(), where say() is annotated by @deprecated
public class Hero {
@Deprecated
public void say(a){
Log.d("Hero"."I have nothing to say");
}
public void speak(a){
Log.d("Hero"."I have a dream"); }}Copy the code
We then call them separately from the IDE
The say() method is underlined by a line, which the compiler recognizes as a reminder
@Override
This should be familiar, reminding subclasses to Override the @override method in their parent class
@SuppressWarnings
Prevent warning meaning. As mentioned earlier, the compiler will warn you when calling a method annotated by @deprecated, and sometimes developers will ignore this warning. They can do this by calling @SuppressWarnings from where they were called
@SuppressWarnings("deprecation")
public void test1(a){
Hero hero = new Hero();
hero.say();
hero.speak();
}
Copy the code
@SafeVarargs
Parameter safety type annotations. Its purpose is to warn developers not to do anything unsafe with arguments, and its existence prevents compilers from generating such warnings
@FunctionalInterface
Functional interface annotations. A Functional Interface is a normal Interface that has a method, for example
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run(a);
}
Copy the code
The Runnable we use in threaded development is a typical FunctionalInterface annotated by @functionalinterface
One might wonder why functional interface tags are useful, because functional interfaces can be easily converted to Lambda expressions. This is another topic, if you are interested, please search for related knowledge points to learn
Annotations and reflections
Annotations are obtained by reflection. You can first determine whether an annotation is applied to a Class object using the isAnnotationPresent() method
Annotations on a class
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}
Copy the code
The Annotation object is then obtained using the getAnnotation() method
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}
Copy the code
Or getAnnotations()
public Annotation[] getAnnotations() {}
Copy the code
The former method returns the Annotation of the specified type, and the latter method returns all annotations annotated to the element. If you get an Annotation that is not null, then you can call their property methods. Such as
Let’s open Up Eclipse and create a new one
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
public int id(a) default- 1;
public String msg(a) default "Hi";
}
Copy the code
@TestAnnotation()
public class HelloWorld {
public static void main(String[] args) {
boolean hasAnnotation = HelloWorld.class.isAnnotationPresent(TestAnnotation.class);
if(hasAnnotation) {
TestAnnotation testAnnotation = HelloWorld.class.getAnnotation(TestAnnotation.class);
System.out.println("id:"+testAnnotation.id());
System.out.println("msg:"+testAnnotation.msg());
}else {
System.out.println("nothing"); }}}Copy the code
The result of the program is
This is the default value for ID and MSG in TestAnnotation
Annotations on properties and methods
In the example above, we just check out the annotations on the class, but the annotations on the properties and methods are still ok
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@TestAnnotation(msg="Hello")
public class HelloWorld {
@Check(value="hi")
int a;
@Perform
public void testMethod(a){}
@SuppressWarnings("deprecation")
public void test1(a){
Hero hero = new Hero();
hero.say();
hero.speak();
}
public static void main(String[] args) {
boolean hasAnnotation = HelloWorld.class.isAnnotationPresent(TestAnnotation.class);
if ( hasAnnotation ) {
TestAnnotation testAnnotation = HelloWorld.class.getAnnotation(TestAnnotation.class);
// Get class annotations
System.out.println("id:"+testAnnotation.id());
System.out.println("msg:"+testAnnotation.msg());
}
try {
// Get the attribute member of the class itself
Field a = HelloWorld.class.getDeclaredField("a");
// Sets the accessible flag of this object to the indicated Boolean value. A value of true indicates that the reflected object should be used without Java language access checks. A value of false indicates that the reflected object should perform Java language access checking.
a.setAccessible(true);
// Get an annotation on a member variable
Check check = a.getAnnotation(Check.class);
if( check ! =null ) {
System.out.println("check value:"+check.value());
} else {
System.out.println("check is null");
}
Method testMethod = HelloWorld.class.getDeclaredMethod("testMethod");
if( testMethod ! =null ) {
// Get the annotation in the method
Annotation[] ans = testMethod.getAnnotations();
for( int i = 0; i < ans.length; i++) { System.out.println("method testMethod annotation:"+ans[i].annotationType().getSimpleName()); }}else {
System.out.println("testMethod is null"); }}catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getMessage());
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.getMessage());
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch blocke.printStackTrace(); System.out.println(e.getMessage()); }}}Copy the code
Viewing the Running result
Note that @Retention(retentionPolicy.runtime) is required if an annotation is to be successfully extracted at RUNTIME
Usage scenarios for annotations
What are annotations really for? Let’s take a look at the official Java documentation
Annotations are a set of metadata that provides data to interpret program code, but annotations are not part of the interpreted code itself. Annotations have no direct effect on how the code works
Annotations are used as follows:
- Provide information to the compiler: The compiler can use annotations to detect errors and warnings
- Compile-time processing: Software tools can be used to generate code, Html documents, or other processing using annotation information.
- Runtime processing: Some annotations can accept code extraction while the program is running
It is important to note that annotations are not part of the code itself
Annotations also do not change the code itself. Annotations are just tools of some tools, mainly for the compiler and other SoftWare tools.
When the developer modiifies the class, method, Field and other members with annotations, these annotations will not take effect by themselves. The developer must provide the corresponding code to extract and process Annotation information. The code that handles extracting and Processing annotations is called APT (Annotation Processing Tool)
chestnuts
To write A testing framework, test programmers for obvious exceptions in their code — Programmer A: I wrote A class called NoBug, because all its methods are error-free — me: Confidence is A good thing, but just in case of accidents, how about I test it? — Programmer A: How do you test it? — Me: Just add @jiecha to all the methods you write — Programmer A: Ok
NoBug.class
public class NoBug {
@CheckError
public void suanShu(a) {
System.out.println("1234567890");
}
@CheckError
public void jiafa(a) {
System.out.println("1 + 1 =" + 1 + 1);
}
@CheckError
public void jianfa(a) {
System.out.println("1-1 =" + (1 - 1));
}
@CheckError
public void chengfa(a) {
System.out.println("3 x 5=" + 3 * 5);
}
@CheckError
public void chufa(a) {
System.out.println("6/0 =" + 6 / 0); }}Copy the code
This code above, some of these methods have the @checkerror annotation on them
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckError {
}
Copy the code
Now you can test the corresponding method for NoBug
public class HelloWorld {
public static void main(String[] args) {
NoBug testobj = new NoBug();
Class clazz = testobj.getClass();
Method[] method = clazz.getDeclaredMethods();
// To record the log information generated by the test
StringBuilder log = new StringBuilder();
// Record the number of exceptions
int errornum = 0;
for (Method m : method) {
// Only methods marked by @checkerror are tested
if (m.isAnnotationPresent(CheckError.class)) {
try {
m.setAccessible(true);
// The target method used to execute an object
m.invoke(testobj, null);
} catch (Exception e) {
// TODO Auto-generated catch block
// e.printStackTrace();
errornum++;
log.append(m.getName());
log.append("");
log.append("has error:");
log.append("\n\r caused by ");
// Record the name of the exception that occurred during the test
log.append(e.getCause().getClass().getSimpleName());
log.append("\n\r");
// Record specific information about exceptions that occur during the test
log.append(e.getCause().getMessage());
log.append("\n\r");
}
}
}
log.append(clazz.getSimpleName());
log.append(" has ");
log.append(errornum);
log.append(" error.");
// Generate a test reportSystem.out.println(log.toString()); }}Copy the code
Viewing the Running result
The chufa() method in the NoBug class has an exception called ArithmeticException because it divides 0
Thus, with annotations I accomplish my own purpose, which is to test someone else’s code
So, when are annotations used? All I can tell you is, it depends what you want to do with it
Annotation Application Example
There are so many ways to use annotations, and Android development has come into contact with the following:
JUnit
JUnit is a testing framework, typically used as follows:
public class MyMathTest {
@Test
public void add(a) {... }}Copy the code
@test marks the method to Test add()
Previous JUnit article portal
ButterKnife
Classic usage
@BindView(R.id.tv_test)
TextView mTv;
Copy the code
Previous article on ButterKnife portal
, etc.
Frank909 wrote in detail and learned a lot (•̀ ω •́)y