Java之 注解

2021-09-02  本文已影响0人  五月笙

什么是注解

概念

An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Annotations have no direct effect on the operation of the code they annotate.

作用

Annotations have a number of uses, among them:
Information for the compiler — Annotations can be used by the compiler to detect errors or suppress warnings.
Compile-time and deployment-time processing — Software tools can process annotation information to generate code, XML files, and so forth.
Runtime processing — Some annotations are available to be examined at runtime.

参考:
Java Annotation
Java Reflection - Annotations

注解的使用

格式

一个注解由一个@符号后面跟字符串组成,例如:

@Entity

java注解里面一般包含一些元素,这些元素类似于属性或者参数,可以用来设置值,比如我们有一个包含两个元素的@Entity注解:

@Entity(name="mzw", job="码农")

该注解有两个元素,name和job,分别赋予了元素值。

位置

注解可以用于描述一个类、接口、方法、方法参数、字段、局部变量等。

@Override
public void mySuperMethod() { ... }

@SuppressWarnings(value = "unchecked")
public void myMethod() { ... }
@Author(
      name = "zphuan",
      date = "3/24/2017"
   )
public class MyClass() { ... }
pulic void myMethod(@RequestParam String s){ ... }
@Autowired
private MyClass myClass;

细节

@SuppressWarnings("unchecked")
public void myMethod() { ... }
@Author(name = "Jane Doe")
@EBook
public class MyClass { ... }
@Author(name = "Jane Doe")
@Author(name = "John Smith")
public class MyClass { ... }

表明有两个人对该类进行了代码编写。

内置注解

java本身提供了三个内置注解:

自定义注解

元注解

元注解就是用来描述注解的注解,在java里面有下面几个元注解:

  1. RetentionPolicy.SOURCE
    注解只存在于源码中,不会存在于.class文件中,在编译时会被忽略掉。
  2. RetentionPolicy.CLASS
    注解只存在于.class文件中,在编译期有效,但是在运行期会被忽略掉,这也是默认范围。
  3. RetentionPolicy.RUNTIME
    在运行期有效,JVM在运行期通过反射获得注解信息。

ElementType.ANNOTATION_TYPE  Annotation type declaration
ElementType.CONSTRUCTOR  Constructor declaration
ElementType.FIELD  Field declaration (includes enum constants)
ElementType.LOCAL_VARIABLE  Local variable declaration
ElementType.METHOD  Method declaration
ElementType.PACKAGE  Package declaration.
ElementType.PARAMETER  Parameter declaration
ElementType.TYPE  Class, interface (including annotation type), or enum declaration

参考:
Java Doc

注解解析

运行时注解

首先,先定义一个注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {

    public String name();

    public String job();
}

上面通过元注解的定义,可以看出来自定义的注解是运行时注解,可以修饰所有的类型。

类注解
@MyAnnotation(name = "mzw", job = "给类添加了一个注解")
public class TestAnnotation { ... }

现在当程序运行起来的时候我想要获取到TestAnnotation中的@MyAnnotation的注解信息:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MyAnnotation annotation = TestAnnotation.class.getAnnotation(MyAnnotation.class);
        Log.e("mzw", "name == " + annotation.name());
        Log.e("mzw", "value == " + annotation.value());
    }
}

运行后执行结果为:

24603-24603/demo.remer.myannotation E/mzw: name == mzw
24603-24603/demo.remer.myannotation E/mzw: value == 给类添加了一个注解
方法注解
public class TestAnnotation {

    @MyAnnotation(name = "mzw", value = "给方法添加了一个注解")
    public void test(){

    }
}

当程序运行时,可以获取到类中test方法注解的信息:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            Class clazz = Class.forName(TestAnnotation.class.getName());
            for (Method method : clazz.getMethods()) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                if (annotation != null) {
                    Log.e("mzw", "name === " + method.getName() + "||" + annotation.name());
                    Log.e("mzw", "value == " + method.getName() + "||" + annotation.value());
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行执行的结果为:

20791-20791/demo.remer.myannotation E/mzw: name === test||mzw
20791-20791/demo.remer.myannotation E/mzw: value == test||给方法添加了一个注解
参数注解
public class TestAnnotation {

    public static void test(@MyAnnotation(name = "参数", value = "参数上的注解") String parameter){ ... }
}

运行程序,可以获取到方法上的参数注解信息:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            Class clazz = Class.forName(TestAnnotation.class.getName());
            for (Method method : clazz.getMethods()) {
                Annotation[][] parameterAnnotations = method.getParameterAnnotations();
                Class[] parameterTypes = method.getParameterTypes();

                int i = 0;
                for (Annotation[] annotations : parameterAnnotations) {
                    Class parameterType = parameterTypes[i++];
                    for (Annotation annotation : annotations) {
                        if (annotation instanceof MyAnnotation) {
                            MyAnnotation myAnnotation = (MyAnnotation) annotation;
                            Log.e("mzw", "param === " + parameterType.getName());
                            Log.e("mzw", "name === " + myAnnotation.name());
                            Log.e("mzw", "value === " + myAnnotation.value());
                        }
                    }
                }
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

运行执行的结果为:

17392-17392/demo.remer.myannotation E/mzw: param === java.lang.String
17392-17392/demo.remer.myannotation E/mzw: name === 参数
17392-17392/demo.remer.myannotation E/mzw: value === 参数上的注解

注意
isAnnotationPresent(AnnotationName.class) 可以判断Target是否被某个注解修饰

上一篇下一篇

猜你喜欢

热点阅读