摘要:本文将带你了解Java开发之注解简单学习,希望本文对大家学JAVA有所帮助。
1、注解的概述:
注解是用来替代配置文件的!你回忆一下,我们以前总是要写一些配置文件,例如web.xml你还记得么?里面要写<servlet>和<servlet-mapping>!谁来读配置文件呢?当然是Tomcat!谁来写配置文件呢?当然是我们来写了!
在Servlet3.0中就可以使用使用注解来代替配置文件,开发者就不用再写配置文件了,而是写注解,然后Tomcat来读取注解。注解也是类,需要定义了才能使用!分别在Servlet3.0中有一个注解类为@WebServlet,然后我们就可以在Servlet中使用
@WebServlet中使用这个注解了。这个注解就是用来替代<servlet>了。然后Tomcat会通过反射来读取注解中的信息!
小结:
注解的语法:@注解名称
注解的作用:替代xml配置文件!
2、Java中的注解:
· @Overrid:作用在方法上的注解。当方法不是重写父类的方法时会报错;
· @Deprecated:作用在方法上。标记该方法为作废方法(已过时);
· @SuppressWarnings:作用在方法上,压制警告。
3、注解的使用:
· 定义注解类:框架的工作
· 使用注解:我们的工作
· 读取注解(反射):框架的工作
4、定义注解类:
定义注解类不能使用class、enum,也不能使用interface,而是使用@interface。
eg.
[java] view plain copy
1. public @interface MyAnn{}
5、使用注解的目标:
注解可以使用在类(接口或枚举)、属性、方法、构造器、包、参数、局部变量。
eg.
[java] view plain copy
1. package cn.ywq;
2.
3. @MyAnn
4. public class MyClass {
5. @MyAnn
6. private int a;
7. @MyAnn
8. public MyClass() {}
9. @MyAnn
10. public void fun1() {}
11. @MyAnn
12. public void fun2(@MyAnn String s) {
13. @MyAnn
14. int n = 10;
15. }
16. }
6、注解的属性:
定义注解时,也可以给出属性。
[java] view plain copy
1. public @interface MyAnn {
2. String value();
3. int value1();
4. }
其中value就是属性!你可能会说,它是一个方法!没错,它是一个方法,但我们非要称之为属性,因为把它当做属性更加好理解。当为注解指定属性后,那么在使用注解时就必须要给属性赋值了:
[java] view plain copy
1. @MyAnn(value1=100,value="hello")
2. public class MyClass {
3. }
注解的属性还可以有默认值,在使用注解时就可以不给带有默认值的属性赋值了。但没有给出默认值的属性还是要赋值的。
[java] view plain copy
1. public @interface MyAnn {
2. String value() default "hello world";
3. int value1();
4. }
5. @MyAnn(value1=100)
6. public class MyClass {
7. }
在使用注解时,如果只给名为value的属性赋值,那么可以不给出属性的名称直接给出值
[java] view plain copy
1. public @interface MyAnn {
2. String value() default "hello world";
3. int value1() default 100;
4. }
5. @MyAnn()
6. public class MyClass {
7. }
8. @MyAnn(value="hello")
9. public class MyClass {
10. }
11. @MyAnn(value1=200)
12. public class MyClass {
13. }
14. @MyAnn(value="hello",value1=200)
15. public class MyClass {
16. }
17. @MyAnn("hello annocation")
18. public class MyClass {
19. }
20. @MyAnn(300)
21. public class MyClass {
22. }
23. @MyAnn("hello",value1=200)
24. public class MyClass {
25. }
cop
· 注解的属性后面要有一对圆括号,而且圆括号内不能给出东西。就像是无参的方法一样;
· 注解的属性类型只能是:基本类型、String、Enum、Class、注解类型、以上类型的一维数组类型;
· 注解的属性可以有默认值,例如:int a() default 100;
· 数组的属性默认值:int[] arr() default {1,2,3},这里不能使用new int[]{1,2,3}
· 使用注解时,在给数组属性赋值时的格式:@MyAnn(arr={1,2,3});
注解属性的类型
> 8种基本类型
> String
> Enum
> Class
> 注解类型
> 以上类型的一维数组类型
当给数组类型的属性赋值时,若数组元素的个数为1时,可以省略大括号。
eg
[java] view plain copy
1. @MyAnno1( //相当于一个注解对象
2. a=100,
3. b="hello",
4. c=MyEnum1.A,
5. d=String.class,
6. e=@MyAnno2(aa=200, bb="world"), 所以此处e也得是一个注解对象
7. f=100 //省略了大括号
8. )
9. public class Demo3 {
10.
11. }
12.
13. @interface MyAnno1 {
14. int a();
15. String b();
16. MyEnum1 c();
17. Class d();
18. MyAnno2 e();
19. int[] f();
20. }
21. @interface MyAnno2{
22. int aa();
23. String bb();
24. }
7、注解的作用目标:(@Target)
在定义注解时可以限制注解的作用目录!例如让注解只能作用在类和方法上。
这需要使用元注解:@Target。该注解有一个属性value,类型为ElementType[],它是枚举类型。
Target注解的源码如下:
[java] view plain copy
1. public @interface Target {
2. ElementType[] value();
3. }
4. public enum ElementType {
5. TYPE,FIELD,METHOD,PARAMETED,CONSTRUCTOR,LOCAL_VARIABLE,ANNOCATION_TYPE,PACKAGE
6. }
在定义注解时,可以使用@Target注解来限制注解的作用目标:
[java] view plain copy
1. @Target({ElementType.TYPE, ElementType.METHOD})
2. public @interface MyAnn {
3. }
这样MyAnn就只能作用在类和方法上的!其中ElementType.TYPE表示类和接口。
[java] view plain copy
1. @MyAnn()
2. public class MyClass {
3. @MyAnn() //报错
4. private int a;
5.
6. @MyAnn()
7. public void fun() {}
8. }
copy
8、注解的保留策略:(@Rentention)
· 注解的保留策略是指,注解是只保留在源代码上,还是保留到class文件上,再或者是类在运行时,可以被类加载器加载到内存中。
· 如果希望注解被反射,那么注解就要保留到运行时,而不是源代码或类文件上。
· 指定注解的保留策略需要使用元注解@Retention,它有一个value属性,类型为RetentionPolicy类型,RetentionPolicy是枚举类型
[java] view plain copy
1. public @interface Retention {
2. RetentionPolicy value();
3. }
4. public enum RetentionPolicy {
5. SOURCE, CLASS, RUNTIME
6. }
下面代码是指定注解保留到运行时:
[java] view plain copy
1. @Retention(RetentionPolicy.RUNTIME)
2. @Target({ElementType.TYPE, ElementType.METHOD})
3. public @interface MyAnn {
4. String value() default "hello";
5. int value1() default 100;
6. }
9、注解处理器
view plain cop
前面我们介绍了如何定义一个注解,并且阐述了定义注解的属性以及注解可以使用的位置等。那么我们的注解如何才能开始工作呢?即我们的注解内部该如何处理?这个时候我们就需要定义一个注解处理器了。
注解处理器定义了该注解的处理逻辑,下边我们举例说明。
要求:定义一个注解 @Retry ,该注解的功能是每隔一定的时间执行一次该方法,一共执行指定的次数。
好的,根据题意,我们可以定义如下的注解。
[java] view plain copy
1. import java.lang.annotation.Retention;
2. import java.lang.annotation.Target;
3. import java.lang.annotation.ElementType;
4. import java.lang.annotation.RetentionPolicy;
5.
6. @Target(ElementType.METHOD) // 指明该注解的作用范围是方法上
7. @Retention(RetentionPolicy.RUNTIME) // 指明该注解在运行时仍保留
8. public @interface Retry {
9. int interval() default 3; // 定义属性,并且拥有默认值
10. int time() default 3000;
11. }
接着是我们的注解处理器:
[java] view plain copy
1. // 注解处理器,定义注解的逻辑处理
2. class RetryProcessor {
3. public void parseMethod(Class<?> clazz) throws Exception{
4. Method[] methods = clazz.getDeclaredMethods(); // 根据.class得到 该类中的method
5. for(final Method method : methods){
6. Retry retry = method.getAnnotation(Retry.class); // 得到该method上的注解信息,可以为null
7. if(retry != null){
8. final int interval = retry.interval(); // 获得注解的属性
9. final int time = retry.time();
10. // 建立一个线程,并且执行method.invoke()方法
11. ExecutorService executorService = Executors.newFixedThreadPool(2);
12. executorService.execute(new Runnable() {
13. @Override
14. public void run() {
15. for (int i = 0; i < interval; i++) {
16. try {
17. // 通过反射执行方法
18. method.invoke(new Object(), "57890");
19. Thread.sleep(time);
20. } catch (Exception e) {
21. e.printStackTrace();
22. }
23. }
24. }
25. });
26. }
27. }
28. }
29. }
测试类如下:
[java] view plain copy
1. public class RetryTest {
2. /*@Retry
3. public static void sayHello(){
4. System.out.println("Hello World");
5. }*/ 如果要使用该方法时,method.invoke(new Object(),null)即可
6. @Retry
7. public static void sayHello(String name){
8. System.out.println("say hello1 " + name);
9. }
10. @Retry(interval = 2, time = 9000)
11. public static void sayHello2(String name){
12. System.out.println("say hello2 " + name);
13. }
14. public static void main(String[] args) throws Exception {
15. RetryProcessor retry = new RetryProcessor();
16. retry.parseMethod(RetryTest.class);
17. }
18. }
如此,我们即定义了一个完整的注解@Retry,实现了在每隔固定的时间执行方法一次,一共执行指定的次数。
总结:
1、注解的定义使用@interface标识
2、注解可以定义属性,并且可以拥有默认值
3、注解可以作用在类(接口或枚举)、属性、方法、构造器、包、参数、局部变量。
4、注解处理器定义了注解的处理逻辑,涉及到反射机制、线程机制等。
以上就介绍了JAVA的相关知识,希望对JAVA有兴趣的朋友有所帮助。了解更多内容,请关注职坐标编程语言JAVA频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号