1、注解html
1.全部的注解都是类。java
2.全部的注解都是Annotation接口的子类。数组
接口摘要ide |
|
全部 annotation 类型都要扩展的公共接口。this |
3.定义方式spa
public @interface TestAnnotation { }
4.能够注解的位置:任何地方均可以,可是要知足注解的具体限制,默认注解能够加在任意位置上code
package com.kdyzm.anotation; @TestAnnotation public class Test { @TestAnnotation private String name; @TestAnnotation public void show(@TestAnnotation String name) { @TestAnnotation String age; System.out.println(name); } }
5.使用注解限制注解的位置htm
使用@Target注解限制自定义注解的注解位置。对象
@Target(value={ElementType.METHOD})//声明只能对方法进行注解,接收数组参数
具体能够限制的类型:ElementType枚举
/* * %W% %E% * * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang.annotation; /** * A program element type. The constants of this enumerated type * provide a simple classification of the declared elements in a * Java program. * * <p>These constants are used with the {@link Target} meta-annotation type * to specify where it is legal to use an annotation type. * * @author Joshua Bloch * @since 1.5 */ public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE }
6.限制注解在运行时是否删除
使用@Retention限制注解的存在范围
@Retention(value=RetentionPolicy.RUNTIME)//声明该注解在运行时保存,即便用方法isAnnotationPresent方法返回值是true
具体的参数见:RetentionPolicy枚举(保留策略枚举)。
/* * %W% %E% * * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.lang.annotation; /** * Annotation retention policy. The constants of this enumerated type * describe the various policies for retaining annotations. They are used * in conjunction with the {@link Retention} meta-annotation type to specify * how long annotations are to be retained. * * @author Joshua Bloch * @since 1.5 */ public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
7.注解的做用
(1)编译时限制做用
public class MyServlet extends HttpServlet { @Override public void doGet(ServletRequest req,String name) throws ServletException, IOException { } }
由于父类没有这个方法,因此加上@Override注解以后就会编译报错。
(2)运行时反射
全部类的字节码对象Class、Field、Method、Constructor都拥有一个方法
|
|
|
|
默认自定义注解在运行时删除,可是经过其它注解能够定义该自定义注解的生存范围。怎样定义见6。
8.注解的实例化
永远不要实例化注解类,由于注解类是经过系统经过反射实例化的。
9.给注解定义属性/方法(官方说法为属性)。
(1)value属性:官方推荐的属性,也是默认的属性,使用方法:public String value();(这种定义方法看上去好像是方法,可是其实是属性,暂且为属性)
(2)修饰符必须是public,能够存在static、final修饰,可是不能有其它修饰符。
(3)默认值:使用关键字default定义,若是没有设置默认值,则在使用注解的时候必须显示赋值才能经过编译。
10.注解定义示例。
package com.kdyzm.anotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value={ElementType.METHOD})//声明只能对方法进行注解,接收数组参数 @Retention(value=RetentionPolicy.RUNTIME)//声明该注解在运行时保存,即便用方法isAnnotationPresent方法返回值是true public @interface MyAnnotation { public String value(); public String name() default "noName"; }
2、使用注解小示例。
1.获取注解的属性值。
使用Class类、Field类、Method类、Constructor类的getAnnotation方法。
|
||
|
|
2.自定义注解小练习。
(1)自定义注解MyAnnotation
package com.kdyzm.anotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(value={ElementType.METHOD})//声明只能对方法进行注解,接收数组参数 @Retention(value=RetentionPolicy.RUNTIME)//声明该注解在运行时保存,即便用方法isAnnotationPresent方法返回值是true public @interface MyAnnotation { public String value(); public String name() default "noName"; }
(2)在UseMyAnnotation类中使用自定义注解
package com.kdyzm.setOnMyAnnotation; import com.kdyzm.anotation.MyAnnotation; //使用自定义注解,该注解只能加在方法上。 public class UseMyAnnotation { private String name; private int age; @MyAnnotation("setName方法") public void setName(String name) { this.name=name; } @MyAnnotation("getName方法") private String getName() { return name; } private int getAge() { return age; } @MyAnnotation("setAge方法") public void setAge(int age) { this.age=age; } }
(3)解析UseMyAnnotation类的全部内容并对注解进行解析。
package com.kdyzm.demo; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import com.kdyzm.anotation.MyAnnotation; //测试自定义注解MyAnnotation的使用,使用MyAnnotation类和UseMyAnnotation类两个类 public class MyTest { public static void main(String[] args) throws Exception { String className="com.kdyzm.setOnMyAnnotation.UseMyAnnotation"; Class cls=Class.forName(className); //实例化该类。 Object obj=cls.newInstance(); //获取该类中的全部方法 Method []methods=cls.getDeclaredMethods(); //遍历该方法数组。 for(Method method:methods) { boolean flag=method.isAnnotationPresent(MyAnnotation.class);//判断是否进行了方法的注解 if(flag)//若是进行了方法的注解 { System.out.print("被注解的方法:"); //判断是不是私有的方法 if(method.getModifiers()==Modifier.PRIVATE) { //若是是私有的方法则设置暴力破解 method.setAccessible(true); System.out.println("该方法私有!方法名为:"+method.getName()); } else { System.out.println("该方法共有!方法名为:"+method.getName()); } //若是被注解了,输出该注解属性值 MyAnnotation annotation=method.getAnnotation(MyAnnotation.class); String value=annotation.value(); String name=annotation.name(); System.out.println("该注解的内容是:"+value+","+name); } else//说明是没有被注解的方法 { System.out.print("没有被注解的方法:"); //判断是不是私有的方法 if(method.getModifiers()==Modifier.PRIVATE) { //若是是私有的方法则设置暴力破解 method.setAccessible(true); System.out.println("该方法私有!方法名为:"+method.getName()); } else { System.out.println("该方法共有!方法名为:"+method.getName()); } } System.out.println(); } } }
(4)运行结果。
没有被注解的方法:该方法私有!方法名为:getAge
被注解的方法:该方法共有!方法名为:setAge
该注解的内容是:setAge方法,noName
被注解的方法:该方法私有!方法名为:getName
该注解的内容是:getName方法,noName
被注解的方法:该方法共有!方法名为:setName
该注解的内容是:setName方法,noName