注解学习总结:
1.注解和注释类似,是对源程序的说明,注释是在源代码级别对源程序进行说明,一旦源代码经过编译后,注释信息都将丢失,而注解不但可以在源代码级别对源程序进行说明,而且可以随源代码一起经过编译在运行时期对程序进行说明,这就是注解较注释强的地方。
2.注解和类类似,也会被编译成class文件,但是生命周期为Source的注解没有对应的class文件,因为他只存在于源代码级别,不会被编译进源代码的class文件中,也不会被加载进内存中,因此要class文件也没有用,对于生命周期是Source的注解,基本上等同于注释。
3.注解的生命周期:定义一个注解时可以声明他的生命周期,声明注解的生命周期用到了元注解@Retention()和枚举类RetentionPolicy,注解的生命周期有:
1.RetentionPolicy.SOURCE:源代码级别的生命周期,也是生命周期最短的,只会存在源代码中不会被编译进源代码的Class文件,更不会随源代码的Class文件一起加载进内存。
2.RetentionPolicy.CLASS:类级别的生命周期,会随源代码一起被编译进源代码的Class文件中,其本身也有对应的Class文件,但不会随源代码的Class文件一起加载进内存。
3.RetentionPolicy.RUNTIME:运行时级别的生命周期,不仅会随源代码一起被编译进源代码的Class文件中,本身也有对应的Class文件,而且也会随源代码的Class文件一起加载进内存。
注:默认的生命周期是Class级别,即不写Retention元注解的话编译器默认为Retention.CLASS.
4.注解的作用域:定义一个注解时可以生命他的作用域,声明注解的作用域用到了元注解@Target()和枚举类ElementType,注解的作用域有:
1.ElementType.FIELD:字段级别作用域,表明该注解可以被声明在字段上。
2.ElementType.METHOD:方法级别作用域,表明该注解可以被声明在方法上
3.ElementType.PACKAGE:包级别作用域,表明该注解可以被声明在包上
4.ElementType.TYPE:类型级别作用域,表明该注解可以被声明在类型上,类型包括类类型,接口类型,枚举类型,注解类型
5.ElementType.CONSTRUCTOR:构造函数级别作用域,表明该注解可以被声明在构造函数上
6.ElementType.LOCAL_VARIABLE:局部变量级别作用域,表明该注解可以被声明在局部变量上
7.ElementType.PARAMETER:参数级别作用域,表明该注解可以被声明在参数上
8.ElementType.TYPE_PARAMETER:类型参数作用域,表明该注解可以被声明在类型参数上
9.ElementType.ANNOTATION_TYPE:注解级别作用域,表明该注解可以被声明在注解上
注:可以为注解声明多个作用域,作用域间用或运算符进行连接
5.Java中的元注解:Java中有四种元注解,元注解和类加载器中的boastLoader类似,因为注解本身也需要被注解,所有需要有不需要被注解的注解,这类注解就是元注解。
1.@Target:声明注解作用域的元注解,用来表明该注解可以被声明在什么地方
2.@Retention:声明注解声明周期的元注解,用来表明该注解在什么级别可用
3.@Document:声明该注解应该被包含进文档中的元注解
4.@Inherited:允许子类继承父类中的注解的元注解
6.Java中内置的三种常用的注解:
1.@Override:表示当前方法的定义将覆盖父类中对应的方法,如果当前方法的签名和父类中不同,编译器就会发出错误提示。
2.@Deprecated:表示当前方法或类已经过时的注解,如果程序员使用了被他注解的方法或类,编译器就会发出警告信息
3.@SuppressWarnings:关闭不当的编译器警告信息,如果程序员不想让编译器对某些代码发出警告信息,可以使用该注解
7.注解的定义和使用:
1.定义注解用到了关键字@interface:
/**
* 注解的定义和接口类似,用到了@interface关键字
*/
public @interface MyAnnotation{
//定义了一个简单注解
}
2.给注解中定义元素,注解中可以使用的类型有:所有的基本数据类型,String,Class,enum,Annotation,以上类型的数组。
/**
* 注解中元素的定义方式和接口中方法的声明方式类似,给
* 注解定义元素时可以给元素定义默认值,用到了关键字
* default关键字,其中不能以null给注解元素赋默认值
*/
@Target(ElementType.METHOD)//给注解声明作用域
@Retention(RetentionPolicy.RUNTIME)//给注解声明生命周期
public @interface SimpleAnnotation{
public int id() default 0;//声明了一个int类型的元素id,并给他设置了默认值0
public String name() default "张三";//声明了一个String类型的元素name,并给他设置了默认值张三
// public String name() default null;//错误,不能用null给注解中的元素赋默认值
}
3.为注解编写注解处理器:
/**
* 如果注解没有对应的注解处理器,那么注解也就和注释差不多了,
* 注解处理器既可以对类的Class文件进行处理,又可以对类的实例对象
* 进行处理,编写注解处理器用到了反射,通过反射得到一个类的Class对象
* 再通过反射得到指定的注解,然后根据注解信息处理被注解的类
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test{//定义一个注解
public String name() default; "张三";//定义一个注解元素
public int age default 20;//定义一个注解元素
}
public class MyClass{//使用注解的测试类
@Test()//使用了默认值的注解
public void show(){
System.out.println("我在方法上通过默认值的方式来使用注解");
}
@Test(name="李四",age=30)//通过给注解中元素赋值的方式使用注解
public void play(){
System.out.println("我在方法上通过给注解元素赋值的方式使用注解");
}
}
public class AnnotationProcess{//注解处理类
public static void main(String[]args){
MyClass obj=new MyClass();//创建一个包含注解的测试类对象
Class mc=obj.getClass();//获得测试类的Class对象
Method[] methods=mc.getMethods();//通过反射取得该类中所有的public方法
for(Method method:methods){//遍历方法数组
if(method.getAnnotation(Test.Class)!=null){//该方法上面有@Test注解
Annotation anno=method.getAnnotation(Test.Class);//取得该方法上面的@Test注解
String name = anno.name();//取得该注解中的name元素值
int age =anno.age();//取得该注解中的age元素值
System.out.println("name="+name+",age="+age);//将注解中的元素信息打印出来
}
}
}
}
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
详细请查看:www.itheima.com