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<String> 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 TypeMethod and Description
类<? extends Annotation>annotationType()

返回此注释的注释类型。

booleanequals(Object obj)

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

inthashCode()

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

StringtoString()

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

四.自定义注解 


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();
}

五.反射机制概念 

 



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 + '\'' +
                '}';
    }
}

六.得到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());

    }
}

八.类的加载内存分析


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

        /*
        1. 加载到内存,会产生一个类对应Class对象
        2. 链接,连接结束后m=0
        3. 初始化
           <clinit>(){
                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类无参构造初始化");
    }
}

九. 分析类的初始化

 


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;
}

十.类加载器 

 


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"));

    }
}

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

Modifier and TypeMethod and Description
<U> 类<? extends U>asSubclass(类<U> clazz)

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

Tcast(Object obj)

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

booleandesiredAssertionStatus()

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

static 类<?>forName(String className)

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

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

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

AnnotatedType[]getAnnotatedInterfaces()

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

AnnotatedTypegetAnnotatedSuperclass()

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

<A extends Annotation>
A
getAnnotation(类<A> annotationClass)

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

Annotation[]getAnnotations()

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

<A extends Annotation>
A[]
getAnnotationsByType(类<A> annotationClass)

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

StringgetCanonicalName()

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

类<?>[]getClasses()

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

ClassLoadergetClassLoader()

返回类的类加载器。

类<?>getComponentType()

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

Constructor<T>getConstructor(类<?>... parameterTypes)

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

Constructor<?>[]getConstructors()

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

<A extends Annotation>
A
getDeclaredAnnotation(类<A> annotationClass)

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

Annotation[]getDeclaredAnnotations()

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

<A extends Annotation>
A[]
getDeclaredAnnotationsByType(类<A> annotationClass)

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

类<?>[]getDeclaredClasses()

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

Constructor<T>getDeclaredConstructor(类<?>... parameterTypes)

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

Constructor<?>[]getDeclaredConstructors()

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

FieldgetDeclaredField(String name)

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

Field[]getDeclaredFields()

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

方法getDeclaredMethod(String name, 类<?>... parameterTypes)

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

方法[]getDeclaredMethods()

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

类<?>getDeclaringClass()

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

类<?>getEnclosingClass()

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

Constructor<?>getEnclosingConstructor()

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

方法getEnclosingMethod()

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

T[]getEnumConstants()

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

FieldgetField(String name)

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

Field[]getFields()

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

Type[]getGenericInterfaces()

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

TypegetGenericSuperclass()

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

类<?>[]getInterfaces()

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

方法getMethod(String name, 类<?>... parameterTypes)

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

方法[]getMethods()

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

intgetModifiers()

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

StringgetName()

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

软件包getPackage()

获取此类的包。

ProtectionDomaingetProtectionDomain()

返回 ProtectionDomain 。

URLgetResource(String name)

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

InputStreamgetResourceAsStream(String name)

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

Object[]getSigners()

获得这个类的签名者。

StringgetSimpleName()

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

类<? super T>getSuperclass()

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

StringgetTypeName()

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

TypeVariable<类<T>>[]getTypeParameters()

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

booleanisAnnotation()

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

booleanisAnnotationPresent(类<? extends Annotation> annotationClass)

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

booleanisAnonymousClass()

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

booleanisArray()

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

booleanisAssignableFrom(类<?> cls)

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

booleanisEnum()

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

booleanisInstance(Object obj)

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

booleanisInterface()

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

booleanisLocalClass()

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

booleanisMemberClass()

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

booleanisPrimitive()

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

booleanisSynthetic()

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

TnewInstance()

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

StringtoGenericString()

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

StringtoString()

将对象转换为字符串。


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 + '\'' +
                '}';
    }

}

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


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 + '\'' +
                '}';
    }

}

十四.获取泛型信息 


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<String,User> map, List<User> list){
        System.out.println("test02");
    }

    public Map<String,User> 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 + '\'' +
                '}';
    }

}

十五.获取注解信息 


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();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/359424.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

4D毫米波雷达分类和工程实现

4D毫米波目标检测信息丰富&#xff0c;可获得目标3维位置信息、径向速度vr和rcs等&#xff0c;能够对目标准确分类。 4D毫米波和激光做好时空同步&#xff0c;可以用激光目标给4D毫米波做标注&#xff0c;提升标注效率。 1 激光用做4D毫米波分类真值 128线激光推理的结果作为4…

计算机网络-数据交换方式(电路交换 报文交换 分组交换及其两种方式 )

文章目录 为什么要数据交换&#xff1f;总览电路交换电路交换的各个阶段建立连接数据传输释放连接 电路交换的特点电路交换的优缺点 报文交换报文交换流程报文交换的优缺点 分组交换分组交换流程分组交换的优缺点 数据交换方式的选择分组交换的两种方式数据报方式数据报方式的特…

基于二值化图像转GCode的双向扫描实现

基于二值化图像转GCode的双向扫描实现 什么是双向扫描双向扫描代码示例 基于二值化图像转GCode的双向扫描实现 什么是双向扫描 在激光雕刻中&#xff0c;双向扫描&#xff08;Bidirectional Scanning&#xff09;是一种雕刻技术&#xff0c;其中激光头在雕刻过程中沿两个方向…

怎么查询鸿蒙真机支持的API版本

1、打开设备的开发者模式与USB调试并通过USB连接上电脑。 2、管理员身份运行cmd。 3、进入hdc.exe所在目录。(鸿蒙OS IDE的SDK下载目录中) 4、输入hdc shell&#xff0c;进入特殊模式 5、输入 getprop hw_sc.build.os.apiversion 查看API版本 6、输入 getprop hw_sc.build…

算法:积木游戏学习数学

一、算法描述 小华和小微一起通过玩积木游戏学习数学。 他们有很多积木&#xff0c;每个积木块上都有一个数字&#xff0c;积木块上的数字可能相同。 小华随机拿一些积木挨着排成一排&#xff0c;请小微找到这排积木中数字相同且所处位置最远的2块积木块&#xff0c;计算他们的…

Java 开发环境 全套包含IDEA

一、JDK配置 1.下载 JDK Builds from Oracle 去这边下载open JDK 2.JDK环境变量配置 按win&#xff0c;打开设置 找到环境变量编辑 这边输入的是你下载的那个JDK的bin的路径 检擦配置是否正确在cmd中输入 二、IDEA安装配置 1.下载&#xff08;社区版&#xff09; JetBrai…

华为---STP(二)---STP报文和STP端口状态

目录 1. STP报文简介 1.1 Configuration BPDU 1.2 TCN BPDU 2. STP交换机端口状态 2.1 STP交换机端口状态表 2.2 STP交换机端口状态迁移过程图 2.3 STP交换机端口状态变化举例说明 3 引起的STP网络拓扑改变的示例 3.1 根桥出现故障 3.2 有阻塞端口的交换机根端口所在…

学习鸿蒙基础(2)

arkts是声名式UI DevEcoStudio的右侧预览器可以预览。有个TT的图标可以看布局的大小。和html的布局浏览很像。 上图布局对应的代码&#xff1a; Entry //入口 Component struct Index {State message: string Hello Harmonyos //State 数据改变了也刷新的标签build() {Row()…

万户 ezOFFICE DocumentEditExcel.jsp SQL注入漏洞

0x01 产品简介 万户OA ezoffice是万户网络协同办公产品多年来一直将主要精力致力于中高端市场的一款OA协同办公软件产品,统一的基础管理平台,实现用户数据统一管理、权限统一分配、身份统一认证。统一规划门户网站群和协同办公平台,将外网信息维护、客户服务、互动交流和日…

Unity3D正则表达式的使用

系列文章目录 unity工具 文章目录 系列文章目录前言一、匹配正整数的使用方法1-1、代码如下1-2、结果如下 二、匹配大写字母2-1、代码如下1-2、结果如下 三、Regex类3-1、Match&#xff08;&#xff09;3-2、Matches()3-3、IsMatch&#xff08;&#xff09; 四、定义正则表达式…

React、React Router、JSX 简单入门快速上手

React、React Router、JSX 简单入门快速上手 介绍特点 JSX使用js表达式渲染列表样式控制注意事项 入门脚手架创建react项目安装目录介绍入口文件解析 组件解析介绍函数式组件类组件 事件绑定注意点定义使用事件对象事件处理函数接收额外参数 组件状态状态的定义使用 组件通信父…

探索水下低光照图像检测性能,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建海底生物检测识别分析系统

海底这类特殊数据场景下的检测模型开发相对来水比较少&#xff0c;在前面的博文中也有一些涉及&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《尝试探索水下目标检测&#xff0c;基于yolov5轻量级系列模型n/s/m开发构建海底生物检测系统》 《基于YOLOv5C3CBAMCBA…

ElementUI Form:Radio 单选框

Radio 单选框 点击下载learnelementuispringboot项目源码 效果图 el-radio.vue 页面效果图 项目里el-radio.vue代码 <script> export default {name: el_radio,data() {return {radio: 1,radio2: 2,radio3: 3,radio4: 上海,radio5: 上海,radio6: 上海,radio7: 上海,r…

微信小程序如何实现点击上传图片功能

如下所示,实际需求中常常存在需要点击上传图片的功能,上传前显示边框表面图片显示大小,上传后将图形缩放到边框大小。 实现如下: .wxml <view class="{{img_src==?blank-area:}}" style="width:100%;height:40%;display:flex;align-items: center;jus…

【C++航海王:追寻罗杰的编程之路】引用、内联、auto关键字、基于范围的for、指针空值nullptr

目录 1 -> 引用 1.1 -> 引用概念 1.2 -> 引用特性 1.3 -> 常引用 1.4 -> 使用场景 1.5 -> 传值、传引用效率比较 1.6 -> 值和引用作为返回值类型的性能比较 1.7 -> 引用和指针的区别 2 -> 内联函数 2.1 -> 概念 2.2 -> 特性 3 -…

聊聊DoIP吧

DoIP是啥? DoIP代表"Diagnostic over Internet Protocol",即互联网诊断协议。它是一种用于在车辆诊断中进行通信的网络协议。DoIP的目标是在现代汽车中实现高效的诊断和通信。通过使用互联网协议(IP)作为通信基础,DoIP使得诊断信息能够通过网络进行传输,从而提…

Uniapp小程序端打包优化实践

背景描述&#xff1a; 在我们最近开发的一款基于uniapp的小程序项目中&#xff0c;随着功能的不断丰富和完善&#xff0c;发现小程序包体积逐渐增大&#xff0c;加载速度也受到了明显影响。为了提升用户体验&#xff0c;团队决定对小程序进行一系列打包优化。 项目优化点&…

近期作业总结(函数,递归,二进制)

二分查找函数 写一个二分查找函数 功能&#xff1a;在一个升序数组中查找指定的数值&#xff0c;找到了就返回下标&#xff0c;找不到就返回-1。 int bin_search(int arr[], int left, int right, int key) {int mid 0;while (left < right) {mid (right left) / 2;if…

Labview 图像处理系统设计

1. 总体主界面设计 前面板界面如下&#xff1a; 界面总共分为一个实时采集加拍照控制模块&#xff0c;两个图像显示模块&#xff08;实时图像显示和直方图显示&#xff09;以及三个图像处理模块 前面板中各模块具体功能及使用说明如下&#xff1a; 1.当实时按钮关闭时&#x…

代码随想录day15--二叉树的应用3

LeetCode110--平衡二叉树 题目描述&#xff1a; 给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; 输入&#xff1a…