注解的简单介绍以及自定义注解

来源:互联网 发布:自学软件编程 编辑:程序博客网 时间:2024/06/07 10:59

注解的使用方法以及自定义注解

注解的简单用法

/*     *  注解是给编译器看的     *  如下是复写的Object类的方法     *  Override代表此方法是复写的     *  如果父类中没有此方法,会报编译错误     */    @Override    public boolean equals(Object obj){        return super.equals(obj);    }    /*     * 表示该方法已过时     */    @Deprecated    public void add(){    }    /*     * 去掉由于没有使用泛型而出现的警告     */    @SuppressWarnings("rawtypes")    public void doit(){        List list=new ArrayList<>();        System.out.println(list);    }

自定义注解

新建一个注解类

/** * @author Administrator * 使用注解可以替代配置文件,将原来配置文件中的信息 * 在注解中描述 */public @interface Annotation1 {String name();//声明一个String属性//声明一个枚举属性,并给出默认值Gender gender() default Gender.FEMALE;Class cla();//声明一个类属性//声明一个注解属性,这样可以嵌套数据MyAnnotation2 my2();//声明一个数组属性,不能这样写default new int[];int [] arr() default {1,2,4};//注解中不能使用集合类型属性/* * Invalid type List for the annotation attribute Annotation1.ss; *  only primitive type, String, Class, annotation, enumeration *   are permitted or 1-dimensional arrays thereof *///List ss();}

Annotation1中的注解属性MyAnnotation2

public @interface MyAnnotation2 {String name();}

使用该注解类

/*     * 使用自定义annotation     */    @Annotation1(name="zhangsan",gender=Gender.MALE,cla=String.class,my2=@MyAnnotation2(name="xxx"))    public void doaa(){    }

注解中名称为“value”的属性,可以直接赋值,但是这只是在注解中只有这一个属性的情况下

public @interface MyAnnotation3 {  String value();} //使用MyAnnotation3@MyAnnotation3("xxx")    public void dobb(){    }

使用注解替代配置文件,将原来配置文件中的信息在注解中描述

存储信息的注解类

/* * @Retention包含RetentionPolicy,通过它指定域 * RetentionPolicy.CLASS * 把注解记录在class文件中,jvm不会保留注解,这是默认值 * RetentionPolicy.RUNTIME * 把注解记录在class文件中,jvm会保留注解 * RetentionPolicy.SOURCE * 编译器直接丢弃这种策略注释   *///下面四个是元Annotation,也就是修饰Annotation的Annotation//-------------------------------------------//定义了该Annotation被保留的时间(一定要在这里声明作用域,否则运行时不能得到该注解)@Retention(RetentionPolicy.RUNTIME)//这个是指定注解用于修饰类的哪个成员@Target({ElementType.METHOD,ElementType.PACKAGE})@Documented//被该注解修饰的注解类将被javadoc工具提取成文档@Inherited//被它修饰的注解将具有继承性//--------------------------------------------------------public @interface DBInfoAnnotation {   String url();   String username();   String pwd();}

在下面的类中使用上面的自定义注解(只是用来模拟,并没有真正连接数据库)

public class DBConnect {    @DBInfoAnnotation(url="jdbc:mysql://localhost:3306/test",username="root",pwd="123")   public Connection getConnection(String url,String username,String pwd){        System.out.println(url);        System.out.println(username);        System.out.println(pwd);        return null;   }}

使用反射获取注解中配置的信息,并执行getConnection方法

public class Demo2 {   public static void main(String[] args) throws Exception{    Class cla=DBConnect.class;    //得到需要运行的方法    Method method=  cla.getMethod("getConnection", String.class, String.class, String.class);DBInfoAnnotation di= method.getAnnotation(DBInfoAnnotation.class);String url=di.url();String username=di.username();String pwd=di.pwd();method.invoke(cla.newInstance(), url,username,pwd);   }}

执行上面的demo,可以打印出DBConnect的getConnection方法使用
注解配置的信息

使用注解将实体类传给方法或类属性供其使用

实体类

public class Person {   private String name;   private int age;public String getName() {    return name;}public void setName(String name) {    this.name = name;}public int getAge() {    return age;}public void setAge(int age) {    this.age = age;}}

传递该实体类的注解

@Retention(RetentionPolicy.RUNTIME)public @interface InjectPerson {String name();int age();}

操作该实体类的Dao

public class PersonDao {@InjectPerson(name="laoli",age=23) private Person person;public Person getPerson() {    return person;}@InjectPerson(name="laowang",age=23)public void setPerson(Person person) {    this.person = person;}}

—————通过注解将person传给方法

/** * @author Administrator *  通过注解将person传给方法 */public class Test {   public static void main(String[] args) throws IntrospectionException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, IllegalArgumentException, InvocationTargetException {    //1.得到要注入的属性       PropertyDescriptor pd=new PropertyDescriptor("person", PersonDao.class);//2.得到要注入的属性需要的类型      Class cla= pd.getPropertyType();//person     //3.得到创建属性需要的对象   Object person=cla.newInstance();     //4得到属性的写方法(set) Method setPerson=pd.getWriteMethod(); //5反射方法上声明的注解 InjectPerson inject=  setPerson.getAnnotation(InjectPerson.class); //6得到注解上声明的信息,填充person对象 Method[] methods=inject.getClass().getMethods(); for(Method m:methods){     String methodName=m.getName();     try{         //如果没有该方法会抛出异常(methodName)         Field f= Person.class.getDeclaredField(methodName);         Object value= m.invoke(inject, null);//得到注解上配置的属性的值         f.setAccessible(true);//如果实体类中的成员变量为private,必须进行此操作         f.set(person, value);     }catch(Exception e){         continue;      } } //7把填充了数据的person通过setPerson方法整到personDao上 PersonDao dao=new PersonDao(); setPerson.invoke(dao, person);//执行personDao的setPerson方法 System.out.println(dao.getPerson().getName());//打印一下,测试是否成功获取   }}

————–通过注解将person传给属性

/** * @author Administrator *  通过注解将person传给属性 */public class Test2 {    public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IntrospectionException {        // TODO Auto-generated method stub        //1.得到需要注入的属性        Field f=PersonDao.class.getDeclaredField("person");        //2得到属性需要的类型        Class cla=f.getType();        System.out.println(cla);        //3创建person        Person person=(Person) cla.newInstance();        //4反射属性的注解        InjectPerson inject=f.getAnnotation(InjectPerson.class);    //5并用注解的信息填充person        Method m[]=inject.getClass().getMethods();        for(Method ms:m){            String methodName=ms.getName();            //看person对象上有没有注解与之对应的属性            try{                //如果没有该方法会抛出异常(methodName)                PropertyDescriptor pd=new PropertyDescriptor(methodName,Person.class);Method set=pd.getWriteMethod();set.invoke(person, ms.invoke(inject, null));            }catch(Exception e){                continue;            }        }        //6.把person赋给dao        PersonDao dao=new PersonDao();        f.setAccessible(true);        f.set(dao, person);        System.out.println(dao.getPerson().getName());    }
0 0