1. 什么是注解
语法:@注解名称
注解的作用:替代xml配置文件!
servlet3.0中,就可以不再使用web.xml文件,而是所有配置都使用注解!
注解是由框架来读取使用的!
2. 注解的使用
- 分析代码(主要用途:替代配置文件); 写配置文件(xml), 注解开发(就是用注解代替配置文件)
3. 定义注解类
class A {} //定义类
interface A{} //定义接口
enum A{} //定义枚举
@interface A{}//所有的注解都是Annotation的子类!
4. 使用注解
注解的作用目标:
-
- 类
- 方法
- 构造器
- 参数
- 局部变量
- 包
1 package Demo;
2
3
4 @MyAnno1
5 public class Demo1 {
6 @MyAnno1
7 private String name;
8
9 @MyAnnol
10 public Demo1(){ }
11
12 @MyAnnol
13 public void fun1() { }
14
15 public void fun2(@MyAnno1 String name) {
16 @MyAnnol
17 String username = "hello";
18
19 // @MyAnno1
20 // System.out.println("hello");//报错
21 }
22 }
23 //定义注解
24 @interface MyAnno1 { }
5. 注解的属性
- 定义属性:
- 格式:
@interface MyAnno1 {
int age();
String name();
}
- 使用注解时给属性赋值
@MyAnno1(age=100, name="zhangSan")
- 注解属性的默认值:在定义注解时,可以给注解指定默认值!
int age() default 100;
在使用注解时,可以不给带有默认值的属性赋值!
- 名为value的属性的特权
当使用注解时,如果只给名为value的属性赋值时,可以省略“value=”,
例如: @MyAnno1(value="hello"),可以书写成 @MyAnno1("hello")
- 注解属性的类型
- 8种基本类型
- String
- Enum
- Class
- 注解类型
- 以上类型的一维数组类型
- 当给数组类型的属性赋值时,若数组元素的个数为1时,可以省略大括号
1 @MyAnno1(
2 a=100,
3 b="hello",
4 c=MyEnum1.A,
5 d=String.class,
6 e=@MyAnno2(aa=100,bb="world"),
7 f={"a1","a2"})
8 public class Demo3 { }
9
10 @interface MyAnno1 {
11 int a();
12 String b();
13 MyEnum1 c();
14 Class d();
15 MyAnno2 e();
16 String[] f();
17 }
18 @interface MyAnno2 {
19 int aa();
20 String bb();
21 }
22 enum MyEnum1{A,B,C;}
6. 注解的作用目标限定以及保存策略限定
6.1 让一个注解,它的作用目标只能在类上,不能在方法上,这就叫作用目标的限定!
- 在定义注解时,给注解添加注解,这个注解是@Target
@Target(value={ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@interface MyAnno1 {}
1 import java.lang.annotation.ElementType;
2 import java.lang.annotation.Target;
3
4 @MyAnno1
5 public class Demo4 {}
6 @Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
7 @interface MyAnno1 {}
6.2 保留策略
- 源代码文件(SOURCE):注解只在源代码中存在,当编译时就被忽略了
- 字节码文件(CLASS):注解在源代码中存在,然后编译时会把注解信息放到了class文件,但JVM在加载类时,会忽略注解!
- JVM中(RUNTIME):注解在源代码、字节码文件中存在,并且在JVM加载类时,会把注解加载到JVM内存中(它是唯一可反射注解!)
限定注解的保留策略
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1 {}
7. 注解解析
-
T getAnnotation(Class<T>annotationType):得到指定类型的注解引用。没有返回null。
-
Annotation[] getAnnotations():得到所有的注解,包含从父类继承下来的。
-
Annotation[] getDeclaredAnnotations():得到自己身上的注解。
-
boolean isAnnotationPresent(Class<?extends Annotation> annotationType):判断指定的注解有没有。
Class、Method、Field、Constructor等实现了AnnotatedElement接口.
import org.junit.Test;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
public class Demo {
@Test
public void fun1() {
//1. 得到作用目标
Class<A> c = A.class;
//2. 获取指定类型的注解
MyAnno1 myAnno1 = c.getAnnotation(MyAnno1.class);
System.out.println(myAnno1.name() + ", "
+ myAnno1.age() + ", " + myAnno1.sex());
}
@Test
public void fun2() throws SecurityException, NoSuchMethodException {
//1. 得到作用目标
Class<A> c = A.class;
Method method = c.getMethod("fun1");
// 2. 获取指定类型的注解
MyAnno1 myAnno1 = method.getAnnotation(MyAnno1.class);
System.out.println(myAnno1.name() + ", "
+ myAnno1.age() + ", " + myAnno1.sex());
}
}
@MyAnno1(name="A类", age=1, sex="男")
class A {
@MyAnno1(name="fun1方法", age=2, sex="女")
public void fun1() { }
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1 {
String name();
int age();
String sex();
}