1.注解的作用和方法:
类
方法
构造器
参数
局部变量
包
2.注解的属性
定义属性
格式:类型 属性名();
@interface MyInvo {
int age();//属性
String name();//属性
}
使用注解时给属性赋值
-->@MyInvo(age=100,name="haha")
注解属性的默认值
int age() default 100;
使用注解时,可以不给带有默认值的属性赋值!
名为value的属性的特权
注解属性的类型
3.名为value的属性的特权
当使用注解时,如果只给名为value的属性赋值时,可以省略“value=” 本来@MyInvo2(age=100)可以写成@MyInvo2(100)
4.注解属性的类型
–>8中基本类型
–>String
–>Enum
–>Class
–>注解类型
–>以上类型的一维数组类型 Integer[]
5.注解的作用目标限定以及保存策略限定
package test;
@MyInvo(age=100,name=”haha”)
@MyInvo1(name=”haha”)
@MyInvo2(100)
@MyInvo3(
a=100,
name=”100”,
c=MyEnum1.A,//枚举行只用一个值即可
d=String.class,
e=@MyAnno2(a=100),
f={1,2,3}//当只有一个元素时,可以省去大括号及f=1
)
public class Demo01{
}
@interface MyInvo3 {
int a();//属性
String name() default “”;//属性
MyEnum1 c();
Class d();
MyAnno2 e();
int[] f();
}
@interface MyInvo {
int age();//属性
String name();//属性
}
@interface MyInvo1 {
int age() default 100;//属性
String name();//属性
}
@interface MyInvo2 {
int value();//属性
String name() default “”;//属性
}
enum MyEnum1{
A,B,C
}
@interface MyAnno2{
int a();
}
注解的target属性,其实就是设置他的属性值即可,设置不同的值作用于不同的地方
以下是ElementType的部分属性
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
package test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@MyAntion()
public class annoDemo02 {
}
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@interface MyAntion{
}
6.注解的作用目标限定以及保存策略限定
6.1让一个注解,他的作用目标能在类上,不能再方法上,这就叫作用目标的限定
在定义注解时,给注解添加注解,这个注解时@Target
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@interface MyAntion{
}
6.2 保留策略
源代码文件:注解只在源代码中存在,当编译时就被忽略了
字节码文件: 注解在源代码中存在,然后编译时会吧注解信息放到了class文件,但JVM在加载类时,会忽略注解!
JVM:注解在源代码、字节码文件中存在,并且在JVM加载类时,会把注解加载到JVM内存中(他是唯一可以反射注解!)
//注解的作用范围,RunTime在运行时可以被使用
@Retention(RetentionPolicy.RUNTIME)
eg:
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAntionDemo{
}
注解的反射
反射泛型信息
Class –>Type.getGenericSupperclass()
Type –> ParameterizedType,把Type强转为ParameterizedType类型!!
ParameterizedType –>参数化类型 =A
ParameterizedType :Type[] getActualTypeArguments(),A中的String Type[]就是Class[],我们就得到了类型参数了!
/* *
//得到子类的类型
Class clazz=this.getClass();
//获取传递给父类参数化类型
Type type=clazz.getGenericSuperclass();
//他就是A
ParameterizedType pType=(ParameterizedType)type;
//他就是一个Class数组
Type[] types= pType.getActualTypeArguments();
//他就是String
Class c=(Class)types[0];
*/
Class c=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
package test;
import org.junit.Test;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
public class Demo04 {
@Test
public void fun1() throws NoSuchMethodException {
/**
* 1.得到作用目标
* */
Class<A1> c=A1.class;
Method method=c.getMethod("fun1");
/**
* 2.获取指定类型的注解
* */
MyAnno07 myAnno07 = method.getAnnotation(MyAnno07.class);
System.out.println(myAnno07.name()+","+myAnno07.age()+","+myAnno07.sex());
}
}
@MyAnno07(name=”A类”,age=1,sex=”男”)
class A1{
@MyAnno07(name=”fun1方法”,age=2,sex=”女”)
public void fun1(){
}
}
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno07{
String name();
int age();
String sex();
}
反射注解
1.要求
注解的保留策略必须是RUNTIME
2.反射注解需要从作用目标上返回
类上的注解,需要使用Class 来获取。
方法上的注解,需要Method来获取。
构造器上的注解,需要Construcator来获取
成员上的,需要使用Field来获取
Class
Method、Constructor 、Field ; AccessibleObject
他们都有一个方法:
Annotation getAnnotation(Class),返回目标上指定类型的注解!
Annotation[] getAnnotations(), 返回目标上所有注解!