java注解(基础)
一、认识注解
1、注解的定义:
java 提供了一种原程序中的元素关联任何信息和元数据的途径和方法。
2、学习注解的目的:
(1)能够读懂别人写的代码,特别是框架相关的代码(框架中使用注解是非常方便的)
(2)让编程更加简洁,代码更为清晰。
3、java 注解分类
(按照运行机制分)
(1)源码注解:注解只有在源码中存在,编译成.class 文件就不存在了。
(2)编译时注解:注解在源码和.class 文件中都存在
(3)运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解
(按照来源分)
(1)来自 jdk 的注解
(2)来自第三方注解
(3)我们自己定义的注解
4、JDK 注解(常见)
(1)@Override 表明此方法覆盖了父类的方法(使用的最多)
(2)@Deprecated 表明此方法过时了
(3)@SuppressWarnings("deprecation") 表明忽略 deprecation 警告
代码示例
1 package Reflect; 2 3 abstract class Father{ 4 public abstract String name(); 5 public abstract int age(); 6 7 @Deprecated//声明此方法过时 8 public abstract void sing(); 9 } 10 public class Test extends Father{ 11 @Override 12 public String name() { 13 // TODO Auto-generated method stub 14 return null; 15 } 16 17 @Override 18 public int age() { 19 // TODO Auto-generated method stub 20 return 0; 21 } 22 23 @Override//表明覆盖了父类的方法 24 public void sing() { 25 System.out.println("Father is singing..."); 26 27 } 28 public static void main(String[] args) { 29 30 @SuppressWarnings("deprecation")//表示忽略 deprecation 的警告 31 Test t=new Test(); 32 t.sing(); 33 34 } 35 }
运行结果:
Father is singing...
5、常见第三方注解
spring 框架、mybatis 框架和 hibernate 框架中有大量的注解
二、自定义注解
1、元注解
(1)@Target 指明注解的作用域
@Target({ElementType.METHOD,ElemenType.TYPE}) 红色部分表示作用域列表
作用域值表
作用域值 | 描述 |
CONSTRUCTOR | 构造方法声明 |
FIELD | 字段声明 |
LOCAL_VARIABLE | 局部变量声明 |
METHOD | 方法声明 |
PACKAGE | 包声明 |
PARAMETER | 参数声明 |
TYPE | 类、接口 |
(2)@Retention 指明注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
生命周期值表
生命周期值 | 描述 |
SOURCE | 只在源码显示,编译时会丢弃 |
CLASS | 编译时会记录到 class 中,运行时忽略 |
RUNTIME | 运行时存在,可以通过反射读取 |
(3)@Inherited 指明注解允许自助借来继承
(4)@Documented 生成 javadoc 时会包含注解
2、自定义注解的语法要求
(1)成员以无参和没有异常方式声明
(2)可以用 defualt 为成员指定一个默认值
(3)成员类型是受限的,合法的类型包括原始类型(基本数据类型)及 String,Class,Annotation,Enumeration。
(4)如果注解只有一个成员,则成员名必须取名为 value,在使用的时候可以忽略成员名和赋值号(=)
(5)注解类可以没有成员,没有成员的注解称为标识注解
代码示例:(自定义一个注解)
package ANNOTATION;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;//先定义元注解的 @Target 坠儿,指明作用域是方法和类接口
@Target({ElementType.METHOD,ElementType.TYPE})
//指明注解的生命周期,运行时存在
@Retention(RetentionPolicy.RUNTIME)
//指明能够被子注解继承
@Inherited
//指明生成 javadoc 时会包含注解
@Documented
public @interface MyAnnotation {String desc(); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">成员以无参和没有异常方式声明</span>
String author();
int age() default 18;//可以用 defualt 为成员指定一个默认值
}
3、使用自定义注解
使用自定义注解的语法:
@< 注解名 >(< 成员名 1>=< 成员值 1>,< 成员名 2>=< 成员值 2>,....)
代码示例:
package ANNOTATION;@ MyAnnotation(desc="I am a boy",author="tom",age=21)
public class AnnotationTest {@ MyAnnotation(desc="I am a girl",author="mary",age=18)
public void girlSing(){
System.out.println("girl is singing...");
}
}
三、解析注解(读取注解中的信息,并对进行一些操作)
概念:通过反射获取类,函数或成员变量上的运行时注解信息,从而实现动态的控制程序运行的逻辑
注解只会继承类上的注解,当一个类去继承一个类时,可以继承该父类已有的注解,但不能继承其父类上的注解,且接口的注解不能被继承。
代码实现:
1 package ANNOTATION; 2 3 import java.lang.annotation.Annotation; 4 import java.lang.reflect.Field; 5 import java.lang.reflect.Method; 6 7 public class Test { 8 9 public static void main(String[] args) throws ClassNotFoundException { 10 //使用类加载器加载类 11 Class c=Class.forName("ANNOTATION.AnnotationTest"); 12 //找到类上面的注解 13 boolean isExist=c.isAnnotationPresent(MyAnnotation.class); 14 if(isExist){ 15 //拿到注解实例 16 MyAnnotation m=(MyAnnotation) c.getAnnotation(MyAnnotation.class); 17 System.out.println("类注解的信息:"+"desc:"+m.desc()+"author:"+m.author()+"age:"+m.age()); 18 } 19 //1、获取方法上面的注解及其信息 ( 知道方法上注解的名称) 20 //获取类中的所有声明的方法 21 Method[] method= c.getDeclaredMethods(); 22 for (Method method2 : method) { 23 boolean isExist1=method2.isAnnotationPresent(MyAnnotation.class); 24 if(isExist1){ 25 MyAnnotation m1=(MyAnnotation) method2.getAnnotation(MyAnnotation.class); 26 System.out.println(method2.getName()+"方法上注解的信息:"+"desc:"+m1.desc()+"author:"+m1.author()+"age:"+m1.age()); 27 } 28 } 29 //2 获取方法上面的所有注解及其信息 30 for (Method method2 : method) { 31 //获取方法上的所有注解 32 Annotation []at=method2.getAnnotations(); 33 for (Annotation annotation : at) { 34 //开始解析 MyAnnotation 的成员值 35 if(annotation instanceof MyAnnotation){ 36 MyAnnotation m3=(MyAnnotation) annotation; 37 System.out.println(method2.getName()+"方法上注解的信息:"+"desc:"+m3.desc()+"author:"+m3.author()+"age:"+m3.age()); 38 } 39 } 40 /* 41 * 不知道方法上有哪些注释,下面代码可以获取注释的一些信息 42 */ 43 for (Method method4 : method) { 44 //获取方法上的所有注解 45 Annotation []at1=method4.getAnnotations(); 46 for (Annotation annotation : at) { 47 //获取注解的 Class 类对象(反射) 48 Class c3=annotation.annotationType(); 49 //打印注解的名称 50 System.out.println("注解名称:"+c3.getName()); 51 //获取注解所有成员变量 52 Method [] m2=c3.getDeclaredMethods(); 53 for (Method method3 : m2) { 54 System.out.println("注解的成员名称:"+method3.getName()); 55 } 56 } 57 } 58 } 59 } 60 }
运行结果:
1 类注解的信息:desc:I am a boy author:tom age:21 2 girlSing 方法上注解的信息:desc:I am a girl author:mary age:18 3 girlSing 方法上注解的信息:desc:I am a girl author:mary age:18 4 注解名称:ANNOTATION.MyAnnotation 5 注解的成员名称:desc 6 注解的成员名称:author 7 注解的成员名称:age
个人关于注解的应用理解:其实质就是对类、方法、成员变量上的注解,通过反射机制获得并进行解析,从而进一步进行操作。