1.注解:或者叫做注释类型,英文单词叫:Annotation
2.注解Annotation是一种引用数据类型,编译之后也是生成xxx.class文件
3.怎么自定义注解呢?语法格式?
【修饰符列表】@interface 注解类型名{
}
4.注解怎么使用,用在什么地方?
注解可以出现在类上、属性上、方法上、变量上等,注解还可以出现在注解类型上
@MyAnnotation //类上
public class AnnotationTest01 {
@MyAnnotation //属性上
private int no;
public AnnotationTest01(){
}
@MyAnnotation
public static void m1() {
@MyAnnotation //变量上
int i=100;
}
@MyAnnotation
public void m2(@MyAnnotation String name,@MyAnnotation int k) {
}
}
@MyAnnotation //接口上
interface MyInterface{
}
@MyAnnotation //枚举上
enum Season{
}
@MyAnnotation //注解可以出现在注解类型上
public @interface OtherAnnotation {
//注解内容
}
5.关于JDK lang包下的注解
@Deprecated :用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
@Override:表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
掌握:Override注解
public @interface Override{}@Override只能注解方法,标识性注解,给编译器作参考用的,编译器看到方法上有这个注解的时候,编译器会自动校验该方法是否重写了父类的方法,如果没有重写,则报错,这个注解只是在编译阶段起作用,和运行时期无关
@SuppressWarnings:指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。
6.元注解:用来标注“注解类型的注解”
常用的元注解:Target、Retention
关于Target注解:这是一个元注解,用来标注“注解类型的注解”,这个Targ注解用来标注“注解类型的注解”可以出现在哪些位置上。
关于Retention注解:这是一个元注解,用来标注“注解类型的注解”,这个Retention注解用来标注“注解类型的注解”最终保存在哪里。
@Retention(RetentionPolicy.SOURCE):表示该注解只被保留在java源文件中
@Retention(RetentionPolicy.CLASS):表示该注解只被保留在class文件中
@Retention(RetentionPolicy.RUNTIME):表示该注解只被保留在class文件中,并且可以被反 射机制所读取
7.1注解中定义属性
如果注解当中有属性,那么必须给属性赋值。(除非该属性使用default指定默认值)
//定义注解
public @interface MyAnnotation {
/**
* 我们通常在注解当中定义属性,以下是MyAnnotation的name属性
* 看着像一个方法,但实际上我们称之为“属性”。
* @return
*/
String name();
String color();
int age() default 25;//给属性指定默认值
}
//使用注解
public class AnnotationTest01 {
//如果注解当中定义的有属性,必须给属性赋值,除非定义的属性有默认值
//@MyAnnotation(属性名=属性值)
@MyAnnotation(name="zhang",color = "红色")//age属性有默认值,可以省略不写
public void m1(){
}
}
7.2注解中的属性value
如果注解的属性名字是value,并且只有一个属性值的话,在使用的时候,该属性名可以省略不写
//定义注解
public @interface OtherAnnotation {
String value();
//int n();
}
//使用注解
public class AnnotationTest02 {
@OtherAnnotation(value="1")
public void m1() {
}
@OtherAnnotation("2")
public void m2() {
}
}
8.反射注解
8.1获取注解中的属性值
首先准备一个注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* public @interface Target {
* ElementType[]value();
* }
* public enum ElementType {//枚举
* FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,ANNOTATION_TYPE,PACKAGE,Type parameter declaration
* TYPE_PARAMETER,Use of a type*TYPE_USE
* }
*/
@Target({ElementType.TYPE,ElementType.METHOD})//属性名是value,可以省略不写。表示注解只能标注类或方法
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "北京大兴";
}
其次是使用注解
@MyAnnotation
public class MyannotionTest {
}
最后通过反射机制读取使用注解的类
public static void main(String[]args) throws Exception {
//先获取这个类
Class c=Class.forName("com.xin.annotation3.MyannotionTest");
//判断该类中是否含有@MyAnnotaion
// System.out.println(c.isAnnotationPresent(MyAnnotation.class));//true
if(c.isAnnotationPresent(MyAnnotation.class)) {
//获取注解对象
MyAnnotation myAnnotation= (MyAnnotation) c.getDeclaredAnnotation(MyAnnotation.class);
//获取注解中属性值
System.out.println(myAnnotation.value());
}
}
8.2获取注解中的方法(步骤和上面一样,就不赘述了)
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
String username();
String password();
}
public class MyAnnotionTest2 {
@MyAnnotation2(username = "xin",password = "123")
public void doSome() {
}
}
import java.lang.reflect.Method;
public class AnnotationTest02 {
public static void main(String[] args) throws Exception {
//获取这个类
Class c=Class.forName("com.xin.annotation3.MyAnnotionTest2");
//获取doSome方法
Method doSome=c.getDeclaredMethod("doSome");
if(doSome.isAnnotationPresent(MyAnnotation2.class)) {
MyAnnotation2 myAnnotation2=doSome.getDeclaredAnnotation(MyAnnotation2.class);
System.out.println("username="+myAnnotation2.username());
System.out.println("password"+myAnnotation2.password());
}
}
}
9.注解在开发中又什么用呢?
需求:假设有这样一个注解,叫做:@MyAnnotation3,这个注解只能出现在类上面,当这个类中必须有一个int类型的id属性。如果没有这个属性就报异常。如果有这个属性则正常执行。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation3 {
}
@MyAnnotation3
public class MyAnnotionTest3 {
int id;
String name;
String pwd;
}
//创建自定义的异常类
public class HasNotIdPropertyException extends RuntimeException{
public HasNotIdPropertyException() {
}
public HasNotIdPropertyException(String s) {
super(s);
}
}
import java.lang.reflect.Field;
public class AnnotationTest03 {
public static void main(String[] args) throws Exception{
Class s=Class.forName("com.xin.annotation3.MyAnnotionTest3");
boolean flag=false;
if(s.isAnnotationPresent(MyAnnotation3.class)) {
Field[] fields=s.getDeclaredFields();
for(Field field:fields) {
if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())) {
flag=true;
break;
}
}
}
if(!flag) {
throw new HasNotIdPropertyException("被MyAnnotation标注的类中必须有一个int类型的id属性");
}
}
}
当MyAnnotionTest3类中有int类型的属性id时:
当MyAnnotionTest3类中有int类型的属性id时
@MyAnnotation3
public class MyAnnotionTest3 {
// int id;
String name;
String pwd;
}