注解(Annotation):
就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取,
并执行相应的处理.
特点:
1, 使用注解时在其前面加上 @ 符号。
2, 通过使用 注解, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息.
3,注解 可以像修饰符一样被使用, 可用于修饰包,类,构造器, 方法,成员变量,参数, 局部变量的声明。
4,注解 能被用来为程序元素(类, 方法, 成员变量等) 设置元数据。
常用注解:
@ Deprecated :表示某个程序元素已过时。
@ Override :表示该方法须要去重写父类中的方法,否则编译器会报错。
@ SuppressWarnings :取消指定的编译器警告。
JDK中的元注解(Annotation ):
@ Retention:指示注解类型的注解要保留多久。用枚举 RetentionPolicy 类来指定
可保留至3种时期:java源文件--->class文件-->内存中的字节码。
对应:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME
如:
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.METHOD})
public @interface MyAnnotation{
String major();
Int age();
}
@ Target :指示注解类型所适用的程序元素的种类。用枚举 ElementType 类来指明。如果注解类型声明中不存在 Target
元注解,则声明的类型可以用在任一程序元素上。如果存在这样的元注解,则编译器强制实施指定的使用限
制。
如:
@Target(value={ElementType.METHOD})
public @interface MyAnnotation{
String major();
Int age();
}
@ Documented :用于指定被该元注解的注解将可被javadoc工具提取成文档。
@ Inherited :被它修饰的注解将具有继承性,如果某个类继承该类,则子类也具有该注解。
注意:如果使用注解类型注解类以外的任何事物,此元注解类型都是无效的。
还要注意,此元注解仅促成从超类继承注解;对已实现接口的注解无效。
自定义注解:
1,使用 @ interface 来声明注解。
如:public @interface MyAnnotation{}
2,加在某个类上
如:@MyAnnotation public class AnnotationText{}
或写成:
@MyAnnotation
public class AnnotationText{}
3,可使用接口中声明方法的方式来声明注解的属性。
如:public @interface MyAnnotation{
String major();
Int age();
}
注解: @MyAnnotation(“我的注解”,12)
注意:如果注解的属性是数组时,且只有一个元素时,{} 可以省略不写
4,可使用 default 关键字指定成员变量的初始值。
如:public @interface MyAnnotation{
String major();
Int age();
String school() default “大学”;
}
注解: @MyAnnotation(“我的注解”,12)
或: @MyAnnotation(“我的注解”,12,”改变值”)
4,没有定义成员的注解称为标记,定义了成员变量的Annotation称为元数据。
5,提取Annotation信息,可使用接口 AnnotatedElement
例一:
/*
* 自定义注解的应用
* 1,定义注解
* 2,加在对象上(类,方法,字段等)
* 3,通过反射调用
* */
package AnnotationText;
@MyAnnotation(name="name",age=12,array=7) //如果数组只有一个元素可以省略[]不写
public class AnnotationDemo {
public static void main(String [] args)
{
//通过反射来判断该类上是否加有该注解
if(AnnotationDemo.class.isAnnotationPresent(MyAnnotation.class))
{
//有就可通过反射来获取里面的对象
MyAnnotation myannotation = (MyAnnotation)
AnnotationDemo.class.getAnnotation(MyAnnotation.class);
System.out.println(myannotation.name());
System.out.println(myannotation.age());
}
}
}
/*
* 自定义注解
* */
package AnnotationText;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME) //注解保留至执行时期,以反射使用, //否则反射无法使用
@Target(ElementType.TYPE) //注解指定其用于类上
public @interface MyAnnotation {
String name();
int age();
int [] array() default {1,2,3};
}
例二:
要求:用注解来限制设置年龄的大小,就是通过反射来完成的
public static void ageText() throws Exception
{
Class clazz = Class.forName("AnnotationText.Person");
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("setAge", int.class);
int agevalue = 46;
//该方法上是否存在该注解
if(method.isAnnotationPresent(AgeAnnotation.class))
{
//有就可通过反射来获取里面的对象
AgeAnnotation ageannotation =
(AgeAnnotation)method.getAnnotation(AgeAnnotation.class);
// System.out.println("min:"+ageannotation.min());
// System.out.println("max:"+ageannotation.max());
if(agevalue<ageannotation.min()||
agevalue>ageannotation.max())
throw new RuntimeException("年龄不正确");
}
method.invoke(obj, agevalue);
Person p = (Person)obj;
System.out.println("年龄:"+p.age);
}
}
//自定义注解
package AnnotationText;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface AgeAnnotation {
int min();
int max();
}
package AnnotationText;
class Person
{
int age;
Person(){}
@AgeAnnotation(min=0,max=130)
public void setAge(int age) //用注解来限制age的范围为 0-130
{
this.age = age;
}
}
心得:
注解就是程序中一些标记符号,来提示程序员在书写代码过种中出现的问题。我们还可以自己定义注解,让其在须要的时候给我们相应的提示。注意:如果要使用反射来获取注解的属性,那么该注解得由元注解@Retention(RetentionPolicy.RUNTIME)来指明其保留到什么时期,否则无法得到字节码。