注解和反射

1、注解

1、内置注解

  • @Override

    表示重写了父类的方法,有此注解的方法必须是重写了其父类的方法。

  • @Deprecated

    表示该方法不推荐被使用或者有更好的方法代替,在其他地方使用该方法时会被划掉。

  • @SuppressWarnings("all")

    表示不检测警告。

2、元注解

可以给内置注解进行注解的注解。

  • @Target()

    表示注解可以使用的位置,有

    /** Class, interface (including annotation type), or enum declaration */
        TYPE,
    ​
        /** Field declaration (includes enum constants) */
        FIELD,
    ​
        /** Method declaration */
        METHOD,
    ​
        /** Formal parameter declaration */
        PARAMETER,
    ​
        /** Constructor declaration */
        CONSTRUCTOR,
    ​
        /** Local variable declaration */
        LOCAL_VARIABLE,
    ​
        /** Annotation type declaration */
        ANNOTATION_TYPE,
    ​
        /** Package declaration */
        PACKAGE,
    ​
        /**
         * Type parameter declaration
         *
         * @since 1.8
         */
        TYPE_PARAMETER,
    ​
        /**
         * Use of a type
         *
         * @since 1.8
         */
        TYPE_USE

     

  • @Retention()

    表示什么时候执行注解。有source、class、runtime,一般自定义注解都写runtime。

    级别:runtime>class>source。

  • @Documented

    表示注解会被javadoc写入。

  • @Inherited

    表示子类可以继承父类的注解。

3、自定义注解

格式:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface 注解名称{
    //参数格式:参数类型 + 参数名称 + ()
    //如:String name();
    //如果只有一个参数。那么最好命名位value,这样可以不用再在注解上写具体的名称。
    //如果有默认值,则可以写:String name() default "";
}

 

2、反射

1、获取Class对象

import java.lang.annotation.*;
​
public class TestDemo {
​
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
​
        //1、通过全包名
        Class stuent = Class.forName("Student");
        System.out.println(stuent.hashCode());
​
        //2、通过对象
        Class student2 = person.getClass();
        System.out.println(student2.hashCode());
​
        //3、通过类名.class
        Class student3 = Student.class;
        System.out.println(student3.hashCode());
​
        //4、基本内置类型的包装类都有TYPE属性
        Class type = Integer.TYPE;
        System.out.println(type);
​
    }
​
}
​
class Person {
    String name;
    int id;
    int age;
​
    public Person() {
    }
​
    public Person(String name, int id, int age) {
        this.name = name;
        this.id = id;
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
}
​
class Student extends Person {
    public Student() {
        this.name = "学生";
    }
}
​
class Teacher extends Person{
    public Teacher(){
        this.name = "老师";
    }
}

 


2、ORM(对象关系映射)

通过反射获取对象的注解及其值。

import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
​
public class Test03 {
​
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("Child");
​
        //获取类的注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
​
        //获得类注解的值
        ClassAnno classAnno= (ClassAnno) c1.getAnnotation(ClassAnno.class);
        System.out.println(classAnno.dbName());
​
        //获得属性注解的值
        Field id = c1.getDeclaredField("id");
        FieldAnno annotation = id.getAnnotation(FieldAnno.class);
        System.out.println(annotation.colName());
        System.out.println(annotation.colType());
        System.out.println(annotation.length());
    }
​
}
​
@ClassAnno(dbName = "db_child")
class Child{
    @FieldAnno(colName = "child_id",colType = "int",length = 10)
    private int id;
    @FieldAnno(colName = "child_age",colType = "int",length = 10)
    private int age;
    @FieldAnno(colName = "child_name",colType = "varchar",length = 5)
    private String name;
​
    public Child(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }
​
    public Child() {
    }
​
    @Override
    public String toString() {
        return "Child{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public int getAge() {
        return age;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public String getName() {
        return name;
    }
​
    public void setName(String name) {
        this.name = name;
    }
}
​
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassAnno{
    String dbName();
}
​
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnno{
    String colName();
    String colType();
    int length();
}

 

可以通过注解内的值来动态生成sql语句来建表等等,多用于框架。

3、常用方法

  • Class对象.getAnnotations()---获取类对象的所有注解

  • Class对象.getDeclaredFields()---获取类的所有属性,无论是private还是public等等

  • Class对象.getDeclaredMethods()---获取类的所有方法

  • 获取类的方法后可以执行类的方法,类的方法对象.invoke(对象,参数),可以执行该方法,如果方法是私有的,则需要关闭权限检查,可以使用:类的方法对象.setAccessible(true)来关闭权限检查。

posted @ 2020-02-13 16:05  Nevesettle  阅读(170)  评论(0编辑  收藏  举报