Java注解和反射

注解和反射

课程:注解和反射02:内置注解_哔哩哔哩_bilibili

一.注解入门 

1.Annotation是jdk1.5开始引入的新技术。

2.Annotation的作用:

不是程序本身,可以对程序作出解释;

可以被其他程序(例如编译器)读取。

3.Annotation的格式

“@注解名”,也可以带参数,例如:@SuppressWarnings(value=“unchcked”)

4.Annotation在哪里使用?

可以附加在package、class、method、field上,相当于给它们添加了额外的辅助信息,还可以通过反射机制编程实现对这些元数据的访问。

package github.Annotation;

public class Test01 extends Object{
    // Override 重写的注解
    @Override
    public String toString(){
        return super.toString();
    }
}

二.内置注解 

package github.Annotation.Demo01;
import java.util.ArrayList;
import java.util.List;

 @SuppressWarnings("all")
public class Test01 extends Object{

    // Override 重写的注解
    @Override
    public String toString(){
        return super.toString();
    }

    // @Deprecated 不推荐使用,但可以使用,或者存在更好的更新方式
    @Deprecated
    public static void test(){
        System.out.println("Deprecated");
    }

    // @SuppressWarnings 镇压警告,方法和类都可以使用
    @SuppressWarnings("all")
    public void test01(){
        List list = new ArrayList<>();
    }

    public static void main(String[] args) {
        test();
    }
}

三.元注解 

元注解的作用就是负责注解其他注解,Java定叉了4个标准的meta- annotation类型,他们被用来提供对其他 annotation类型作说明。

这些类型和它们所支持的类在 java. lang annotation包中可以找到。(@Target,@Retention,@Documented, @Inherited)


import java.lang.annotation.*;


public class TestAnnotation {
    @MyAnnotion
    public void test(){
    }
}

// 定义一个注解

// 一.Target 注解可以用在什么地方, ElementType.METHOD 方法上有效,ElementType.TYPE类上有效
@Target(value = ElementType.METHOD)

// 二.@Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期。
// RUNTIME > CLASS > SOURCES
@Retention(value = RetentionPolicy.RUNTIME)

// 三.@Documented 表示是否将我们的注解生成在Javadoc中
@Documented

// 四.@Inherited 子类可以继承父类的注解
@Inherited

@interface MyAnnotion{
    
}

Interface Annotation方法

Modifier and Type Method and Description
annotationType()

返回此注释的注释类型。

boolean equals(Object obj)

如果指定的对象表示在逻辑上等同于该注释的注释,则返回true。

int hashCode()

返回此注释的哈希码,定义如下:

String toString()

返回此注释的字符串表示形式。

四.自定义注解 


import java.lang.annotation.*;


public class TestAnnotation {
    @MyAnnotion(id=1,name = "fuck")
    public void test(){
    }
    
    @MyAnnotion2(value = "value")
    public void test2() {
        
    }
}

@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotion{
    // 注解的参数: 参数类型 + 参数名()
    // 默认值default
    int id();
    String name();

    int age() default -1;

}

@Target(ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@interface  MyAnnotion2{
    // 如果只有一个值,那么默认value();
    String value();
}

五.反射机制概念 

 Java注解和反射_第1张图片Java注解和反射_第2张图片



public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        // 通过反射获取class对象,包名+类名
        Class name = Class.forName("User");
        System.out.println(name);
        Class c1 = Class.forName("User");
        Class c2 = Class.forName("User");
        Class c3 = Class.forName("User");
        Class c4 = Class.forName("User");
        
        // 一个类在内存中只有一个Class对象
        // 一个类被加载后,类的整个结构都会被封装在Class对象中
        // c1~c4哈希值相同,证明一个类在内存中只有一个Class对象
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
    }
}
// 实体类:pojo entity
class User{
    private int id;
    private int age;
    private String name;
    public User() {
    }
    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

Java注解和反射_第3张图片

六.得到Class类的几种方式 


public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("这个人是:" + person);

        // 方式一:通过对象查询
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());

        // 方式二:forName获得
        Class c2 = Class.forName("Student");
        System.out.println(c2.hashCode());

        // 方式三:通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3.hashCode());

        // 方式四:基本类型的包装类都有一个Type
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        // 获得父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}
class Person{
    String name;
    public Person() {
    }
    public Person(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "name=" + name;
    }
}
class Student extends Person{
    public Student() {
        this.name = "学生";
    }
}
class Teacher extends Person{
    public Teacher(){
        this.name = "老师";
    }
}

七. 所有类型的Class对象


import java.lang.annotation.ElementType;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException {

        Class c1 = Object.class;    // 类
        Class c2 = Comparable.class;    // 接口
        Class c3 = String[].class; // 一维数组
        Class c4 = int[][].class; // 二维数组
        Class c5 = Override.class; // 注解
        Class c6 = ElementType.class; // 枚举
        Class c7 = Integer.class; // 基本数据类型
        Class c8 = void.class; // void
        Class c9 = Class.class; // class

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

        // 只要元素类型与维度一样,就是同一个Class
        int[] a = new int[10];
        int[] b = new int[100];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());

    }
}

Java注解和反射_第4张图片

八.类的加载内存分析


public class Test05 {
    public static void main(String[] args) {
        A a = new A();
        System.out.println(A.m);

        /*
        1. 加载到内存,会产生一个类对应Class对象
        2. 链接,连接结束后m=0
        3. 初始化
           (){
                System.out.println("A类静态代码块初始化");
                m = 300;
                m = 100;
         }
         */
    }
}
class A{
    static{
        System.out.println("A类静态代码块初始化");
        m=300;
    }
    static int m=100;
    public A(){
        System.out.println("A类无参构造初始化");
    }
}

Java注解和反射_第5张图片Java注解和反射_第6张图片

九. 分析类的初始化

 Java注解和反射_第7张图片


public class Test {
    static{
        System.out.println("Main类被加载!");
    }

    public static void main(String[] args) throws ClassNotFoundException {
        // 一.主动调用,反射也会产生主动引用
        // 1.Son son = new Son();
        // 2.Class.forName("Son");
        // 输出:
        // Main类被加载!
        // 父类被加载
        // 子类被加载



        // 二.不会产生类的引用的方法
        // 1.System.out.println(Son.b);
        // 输出:
        // Main类被加载!
        // 2

        // 2.Son[] array = new Son[5];
        // 输出:
        // Main类被加载!
        
        // 3.System.out.println(Son.a);
        // 输出:
        // Main类被加载!
        // 1
    }
}

class Father{
    static final int b=2;
    static {
        System.out.println("父类被加载");
    }
}
class Son extends Father{
    static {
        System.out.println("子类被加载");
        m=100;
    }
    static int m=300;
    static final int a=1;
}

十.类加载器 

 Java注解和反射_第8张图片Java注解和反射_第9张图片


public class Test {
    public static void main(String[] args) throws ClassNotFoundException {

        // 获取系统类的加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);

        // 获取系统类加载器的父类加载器-->扩展类加载器    jre1.8.0_91\lib\ext
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);

        // 获取扩展类加载器父类加载器-->根加载器(c/c++)  jre1.8.0_91\lib\rt.jar
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);

        // 测试当前类是哪个加载器加载的
        ClassLoader classLoader = Class.forName("Test").getClassLoader();
        System.out.println(classLoader);

        // 测试JDK内置的类是谁加载的
        classLoader = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(classLoader);

        // 如何获得系统类加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));

    }
}

Java注解和反射_第10张图片

十一.获取类的运行时结构 

Modifier and Type Method and Description
 类 asSubclass(类 clazz)

这个 对象来表示由指定的类对象表示的类的子类。

T cast(Object obj)

施放一个目的是通过本表示的类或接口 对象。

boolean desiredAssertionStatus()

如果要在调用此方法时初始化该类,则返回将分配给此类的断言状态。

static 类 forName(String className)

返回与给定字符串名称的类或接口相关联的 对象。

static 类 forName(String name, boolean initialize, ClassLoader loader)

使用给定的类加载器返回与给定字符串名称的类或接口相关联的 对象。

AnnotatedType[] getAnnotatedInterfaces()

返回一个 AnnotatedType对象的数组, AnnotatedType使用类型指定由此 AnnotatedType对象表示的实体的超级  。

AnnotatedType getAnnotatedSuperclass()

返回一个 AnnotatedType对象,该对象表示使用类型来指定由此 对象表示的实体的 类。


A
getAnnotation(类 annotationClass)

返回该元素的,如果这样的注释 否则返回null指定类型的注释。

Annotation[] getAnnotations()

返回此元素上 存在的注释。


A[]
getAnnotationsByType(类 annotationClass)

返回与此元素相关 联的注释 。

String getCanonicalName()

返回由Java语言规范定义的基础类的规范名称。

类[] getClasses()

返回包含一个数组 表示所有的公共类和由此表示的类的成员接口的对象 对象。

ClassLoader getClassLoader()

返回类的类加载器。

getComponentType()

返回 数组的组件类型的Class。

Constructor getConstructor(类... parameterTypes)

返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 函数。

Constructor[] getConstructors()

返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 对象。


A
getDeclaredAnnotation(类 annotationClass)

如果这样的注释 直接存在 ,则返回指定类型的元素注释,否则返回null。

Annotation[] getDeclaredAnnotations()

返回 直接存在于此元素上的注释。


A[]
getDeclaredAnnotationsByType(类 annotationClass)

如果此类注释 直接存在或 间接存在,则返回该元素的注释(指定类型)。

类[] getDeclaredClasses()

返回一个反映所有被这个 对象表示的类的成员声明的类和 对象的数组。

Constructor getDeclaredConstructor(类... parameterTypes)

返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 函数。

Constructor[] getDeclaredConstructors()

返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组  。

Field getDeclaredField(String name)

返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 对象。

Field[] getDeclaredFields()

返回的数组 Field对象反映此表示的类或接口声明的所有字段 对象。

方法 getDeclaredMethod(String name, 类... parameterTypes)

返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 对象。

方法[] getDeclaredMethods()

返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。

getDeclaringClass()

如果由此 对象表示的类或接口是另一个类的成员,则返回表示其声明的类的 对象。

getEnclosingClass()

返回底层类的即时封闭类。

Constructor getEnclosingConstructor()

如果此对象表示构造函数中的本地或匿名类,则返回表示底层类的立即封闭构造函数的Constructor对象。

方法 getEnclosingMethod()

如果此对象表示方法中的本地或匿名类,则返回表示基础类的即时封闭方法的方法对象。

T[] getEnumConstants()

返回此枚举类的元素,如果此Class对象不表示枚举类型,则返回null。

Field getField(String name)

返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 对象。

Field[] getFields()

返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 对象。

Type[] getGenericInterfaces()

返回 Type表示通过由该对象所表示的类或接口直接实现的接口秒。

Type getGenericSuperclass()

返回 Type表示此所表示的实体(类,接口,基本类型或void)的直接超类  。

类[] getInterfaces()

确定由该对象表示的类或接口实现的接口。

方法 getMethod(String name, 类... parameterTypes)

返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 对象。

方法[] getMethods()

返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 对象,包括那些由类或接口和那些从超类和超接口继承的声明。

int getModifiers()

返回此类或接口的Java语言修饰符,以整数编码。

String getName()

返回由 对象表示的实体(类,接口,数组类,原始类型或空白)的名称,作为 String 。

软件包 getPackage()

获取此类的包。

ProtectionDomain getProtectionDomain()

返回 ProtectionDomain 。

URL getResource(String name)

查找具有给定名称的资源。

InputStream getResourceAsStream(String name)

查找具有给定名称的资源。

Object[] getSigners()

获得这个类的签名者。

String getSimpleName()

返回源代码中给出的基础类的简单名称。

getSuperclass()

返回 表示此所表示的实体(类,接口,基本类型或void)的超类  。

String getTypeName()

为此类型的名称返回一个内容丰富的字符串。

TypeVariable<类>[] getTypeParameters()

返回一个 TypeVariable对象的数组,它们以声明顺序表示由此 GenericDeclaration对象表示的通用声明声明的类型变量。

boolean isAnnotation()

如果此 对象表示注释类型,则返回true。

boolean isAnnotationPresent(类 annotationClass)

如果此元素上 存在指定类型的注释,则返回true,否则返回false。

boolean isAnonymousClass()

返回 true当且仅当基础类是匿名类时。

boolean isArray()

确定此 对象是否表示数组类。

boolean isAssignableFrom(类 cls)

确定由此 对象表示的类或接口是否与由指定的Class 表示的类或接口相同或是超类或 接口。

boolean isEnum()

当且仅当该类在源代码中被声明为枚举时才返回true。

boolean isInstance(Object obj)

确定指定的Object是否与此 Object表示的对象分配  。

boolean isInterface()

确定指定 对象表示接口类型。

boolean isLocalClass()

返回 true当且仅当基础类是本地类时。

boolean isMemberClass()

返回 true当且仅当基础类是成员类时。

boolean isPrimitive()

确定指定 对象表示一个基本类型。

boolean isSynthetic()

如果这个类是一个合成类,返回true ; 返回false其他。

T newInstance()

创建由此 对象表示的类的新实例。

String toGenericString()

返回描述此 的字符串,包括有关修饰符和类型参数的信息。

String toString()

将对象转换为字符串。


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("User");

        // 一.获得类的名字
        System.out.println(c1.getName());// 获得包名 + 类名
        System.out.println(c1.getSimpleName());// 获得类名
        System.out.println("=======================");

        // 二.获得类的成员变量
        Field[] fields = c1.getFields();// 只能找到public属性
        for (Field field : fields) {
            System.out.println("getFields:" + field);
        }
        fields = c1.getDeclaredFields();// 找到全部的属性
        for (Field field : fields) {
            System.out.println("getDeclaredFields:" + field);
        }
        // 获得指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name);
        System.out.println("=======================");


        // 三.获得类的方法
        Method[] methods = c1.getMethods(); // 获得本类及父类的全部public方法
        for (Method method : methods) {
            System.out.println("getMethods:" + method);
        }

        methods = c1.getDeclaredMethods(); // 获得本类的所有方法
        for (Method method : methods) {
            System.out.println("getDeclaredMethods:" + method);
        }

        // 获得指定的方法 方法的重载
        Method getName = c1.getMethod("getName", null);// 无参
        Method setName = c1.getMethod("setName", String.class);// 有参
        System.out.println(getName);
        System.out.println(setName);

        // 获得类的构造器
        System.out.println("=======================");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("getConstructors:" + constructor);
        }
        constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("getDeclaredConstructors:" + constructor);
        }
        // 获得指定的构造器
        Constructor declaredConstructor = c1.getDeclaredConstructor(int.class,int.class,String.class);
        System.out.println("指定构造器" + declaredConstructor);
    }

}
// 实体类:pojo entity
class User {
    private int id;
    private int age;
    private String name;

    public User() {
    }

    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

}

Java注解和反射_第11张图片Java注解和反射_第12张图片

十二.动态创建对象执行方法 


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {

        // 获得Class对象
        Class c1 = Class.forName("User");

        // 一.调用了类的无参构造器
        User user = (User) c1.newInstance();
        System.out.println(user);// User{id=0, age=0, name='null'}

        // 二.通过构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(int.class,int.class,String.class);
        User user1 = (User) constructor.newInstance(1,3,"fuck");
        System.out.println(user1);// User{id=1, age=3, name='fuck'}

        // 三.通过反射调用普通方法
        User user2 = (User) c1.newInstance();
        // 通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        // invoke:激活 (对象,"方法值")
        setName.invoke(user2, "some");
        System.out.println(user2.getName());// some

        // 五.通过反射操作成员变量
        User user3 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        // 不能直接操作私有属性,我们需要关闭程序的安全检测,属性或方法的setAccessible(true)
        // 设置安全检测
        name.setAccessible(true);
        name.set(user3, "some2");
        System.out.println(user3.getName());// some2
    }

}
// 实体类:pojo entity
class User {
    private int id;
    private int age;
    private String name;

    public User() {
    }

    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

}

十三.性能比对 


import java.lang.reflect.Method;

public class Test {
    public static void main(String[] args) throws Exception {

        test01();
        test02();
        test03();
    }

    // 一.普通方式调用
    public static void test01() {
        User user = new User();
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }

        long endTime = System.currentTimeMillis();
        System.out.println("普通方式执行10亿次:" + (endTime - startTime) + "ms");
    }

    // 二.反射方式调用
    public static void test02() throws Exception {
        User user = new User();
        Class c1 = user.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();
        System.out.println("反射方式执行10亿次:" + (endTime - startTime) + "ms");
    }

    // 三.反射方式调用,关闭检测
    public static void test03() throws Exception {
        User user = new User();
        Class c1 = user.getClass();

        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }

        long endTime = System.currentTimeMillis();
        System.out.println("反射方式执行10亿次,关闭检测:" + (endTime - startTime) + "ms");
    }

}

// 实体类:pojo entity
class User {
    private int id;
    private int age;
    private String name;

    public User() {
    }

    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

}

Java注解和反射_第13张图片

十四.获取泛型信息 


import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Test {
    public void test02(Map map, List list){
        System.out.println("test02");
    }

    public Map test03(){
        System.out.println("Test03");
        return null;
    }


    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test.class.getMethod("test02", Map.class, List.class);
        Type[] genericParameterTypes = method.getGenericParameterTypes();

        for (Type genericParameterType : genericParameterTypes){
            System.out.println("#" + genericParameterType);
            if(genericParameterType instanceof ParameterizedType){
                Type[] typeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type typeArgument : typeArguments){
                    System.out.println(typeArgument);
                }
            }
        }

        System.out.println("======================================================");

        method = Test.class.getMethod("test03", null);
        Type returnType = method.getGenericReturnType();

        if(returnType instanceof ParameterizedType){
            Type[] typeArguments = ((ParameterizedType) returnType).getActualTypeArguments();
            for (Type typeArgument : typeArguments){
                System.out.println(typeArgument);
            }
        }
    }

}

// 实体类:pojo entity
class User {
    private int id;
    private int age;
    private String name;

    public User() {
    }

    public User(int id, int age, String name) {
        this.id = id;
        this.age = age;
        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;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

}

Java注解和反射_第14张图片

十五.获取注解信息 


import java.lang.annotation.*;
import java.lang.reflect.Field;

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {

        Class c1 = Class.forName("Student");

        // 通过反射获取注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

        // 获得注解value
        TableDoris tableDoris = (TableDoris) c1.getAnnotation(TableDoris.class);
        String value = tableDoris.value();
        System.out.println(value);

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++");

        // 获得成员变量注解
        Field name = c1.getDeclaredField("name");
        FiledDoris annotation = name.getAnnotation(FiledDoris.class);
        System.out.println(annotation.columnName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());
    }
}


@TableDoris("db_student")
class Student {
    @FiledDoris(columnName = "db_id", type = "int", length = 10)
    private int id;
    @FiledDoris(columnName = "db_age", type = "int", length = 3)
    private int age;
    @FiledDoris(columnName = "db_name", type = "varchar", length = 200)
    private String name;
    public Student() {
    }
    public Student(int id, int age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student2{" +
                "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 TableDoris {
    String value();
}

// 成员变量注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FiledDoris {
    String columnName();
    String type();
    int length();
}

Java注解和反射_第15张图片

你可能感兴趣的:(java,开发语言)