反射与注解的使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射与注解的使用相关的知识,希望对你有一定的参考价值。

作用:注解是附加在代码中的一些信息,用于编译、运行时解析和使用,起到说明配置作用

主要学习两方面1 元注解,2 自定义注解

一、元注解

包括:[email protected],  [email protected]  [email protected], [email protected] 几种

1 @Target

  作用:用于描述注解的使用范围(即 注解是描述:包、类、字段、方法、参数、接口等)

  取值:1.CONSTRUCTOR:用于描述构造器

    2.FIELD:用于描述域

    3.LOCAL_VARIABLE:用于描述局部变量

    4.METHOD:用于描述方法

    5.PACKAGE:用于描述包

    6.PARAMETER:用于描述参数

    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Target(ElementType.TYPE) //注解用于描述类的

public @interface Table {

    /**

     * 数据表名称注解,默认值为类名称

     * @return

     */

    public String tableName() default "className";

}

@Target(ElementType.FIELD) //注解用在字段上

public @interface NoDBColumn {

}

[email protected]

  作用:描述注解的生命周期(1 仅存在源码中,不会被编译 2 存在编译器中,不会在运行中取到 3 存在与类运行期,运行时可以通过反射读取)

  取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留)

    2.CLASS:在class文件中有效(即class保留)

    3.RUNTIME:在运行时有效(即运行时保留)

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)//注解可以在运行期通过反射取得

public @interface Column {

    public String name() default "fieldName";

}

[email protected],

 @Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

[email protected]

@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类

二、自定义注解

      使用@interface自定义注解,自动继承了java.lang.annotation.Annotation接口,其中每一个方法声明一个配置参数,方法名称就是参数名称,

  返回值就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

例子:两个注解,分别标识实体对应的表和数据库中字段

1 类注解

@Target(value=ElementType.TYPE)//表示该注解用于类上面  
@Retention(RetentionPolicy.RUNTIME) //运行时可以通过反射取得  
public @interface Table {  
    public String name() default "";  
}  

2 属性注解,并且注解有两个属性

Target(value=ElementType.FIELD)  
@Retention(RetentionPolicy.RUNTIME
public @interface Column {  
    public String value() default "";   
    public boolean isKey() default false;  
}  

3 实体

package anotation;  
  
@Table(name="s_user")  
public class User {  
      
    @Column(value="id",isKey=true)  
    private Integer id;  
      
    @Column("s_name") /<span style="color: #ff6600;">/没有指定注解的name 则默认name为value 等同于 value="s_name"</span>  
    private String name;  
      
    @Column(value="s_age")  
    private Integer age;  
      
    public Integer getId() {  
        return id;  
    }  
    public void setId(Integer id) {  
        this.id = id;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public Integer getAge() {  
        return age;  
    }  
    public void setAge(Integer age) {  
        this.age = age;  
    }  
}  

  4  测试类,通过反射得到类的各种信息

public class Test {  
      
    public static void main(String[] args) throws  Exception {  
        User user = new User();  
        user.setId(1);  
        user.setName("wang");  
        user.setAge(89);  
          
//      Class<User> userClazz = (Class<User>) Class.forName( "anotation.User");  
        Class  userClazz = user.getClass();  
        Table table = (Table) userClazz.getAnnotation(Table.class); //得到类的注解   
        System.out.println("表名称 : "+table.name() ); //取得注解的名称 属性  
          
        Field[]  fields = userClazz.getDeclaredFields(); //得到所有的 对象的属性   
        for(int i=0;i<fields.length;i++ ){  
            Field field = fields[i];  
              
            Column column  = field.getAnnotation(Column.class );//得到属性上的注解   
            System.out.println( "column的注解名称:"+column.value()+"   注解:isKey===  "+column.isKey() );//打印属性上的注解  
              
            String fieldName = field.getName(); //得到属性名称   
            Class clazz = field.getType();//得到属性类型   
            System.out.println(fieldName + "   字段类型    "+clazz );  
              
            field.setAccessible(true);//可以访问私有变量   
            System.out.println( fieldName + "  调用字段变量取得字段值  "+ field.get(user ) );//打印对象的该属性的值   
            Method method = userClazz.getMethod("get"+toUpperCaseFirstOne(fieldName) );//调用get取得该对象的值  
            System.out.println( fieldName + "  调用字段get方法取出字段值  "+  method.invoke(user) );  
              
              
            System.out.println("判断字段类型是否为整形:"+( clazz==Integer.class));//判断一个字段的类型    
            System.out.println( "============");  
              
        }  
//      Object name = 1;  
//      System.out.println( name.getClass().equals( Integer.class) );  
          
    }  
      
  
    /** 
     * 首字母转大写 
     * @param s 
     * @return 
     */  
    public static String toUpperCaseFirstOne(String s)  
    {  
        if(Character.isUpperCase(s.charAt(0)))  
            return s;  
        else  
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();  
    }  
}  


http://username2.iteye.com

以上是关于反射与注解的使用的主要内容,如果未能解决你的问题,请参考以下文章

反射与注解的使用

java反射与注解结合使用(根据传入对象输出查询sql)

Java 注解与反射 基础

JAVA基础:注解与反射的使用方法与场景

注解与反射

注解与反射