Java注解与反射的使用

学前须知

具有Java基础知识,包括JVM类加载,反射等基础。
反射是框架的前提,通过注解和反射机制,java实现了动态语言的一部分特性

元注解

Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。

java.lang 中的注解

@Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误。
@Deprecated - 标记过时方法。如果使用该方法,会报编译警告。有这个注解的方法不建议使用
@SuppressWarnings - 指示编译器去忽略注解中声明的警告。去除告警波浪线,专治强迫症。

java.lang.annotation中的注解

@Target - 注解使用的范围,比如包,类,方法,字段
@Retention - 表示需要在什么级别保存该注释信息,用于描述注解的生命周期(一般都是RUNTIME级别)
@Documented - 标记这些注解是否包含在javadoc中
@Inherited - 说明子类可以继承父类的注解

// 使用注解
@MyAnnotation
public class Test01 {

}
// 定义一个注解
// 注解可以用在哪些地方
@Target(value = {ElementType.METHOD,ElementType.TYPE})
// 注解在什么地方有效,一般是Runtime
@Retention(value = RetentionPolicy.RUNTIME)
// 将注解生成在JavaDoc中
@Documented
// 子类继承父类注解
@Inherited
// 定义一个注解
@interface MyAnnotation{

}

注解的定义和传参

// 无默认值的注解
@MyAnnotation2(name = "qwer")
public class Test02 {
}
// 参数默认为value,且有默认值的注解
@MyAnnotation3
class Test02_2 {
}
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    // 默认值名是value
    String value() default "";
    // 定义变量后面要加()
    String name();
    // 可以给变量赋默认值
    int age() default 18;
}
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
    // 默认值名是value
    String value() default "默认值";
}

反射

Reflection (反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一 个类只有
一个Class对象), 这个对象就包含了完整的类的结构信息。我们可以通过这个对
象看到类的结构。这个对象就像一面镜子, 透过这个镜子看到类的结构,所以,
我们形象的称之为:反射
在这里插入图片描述

五种获取Class对象的方法

在这里插入图片描述

反射的使用

public class Test03 {
    public static void main(String[] args) throws Exception{
        Class c1 = Class.forName("Test");
        Method methods[] = c1.getMethods();

        System.out.println("获取到method[0]方法名 "+methods[0].getName());

        // 注意!,获取类的方法顺序与类定义方法的顺序不一定一致 多次执行结果会有所不同
        // 通过反射,调用空参方法和有参方法
        methods[0].invoke(new Test(),null);
        methods[1].invoke(new Test(),"aaa"); //String.Class
        System.out.println("============================");
        Class c2 = Class.forName("Person");
        Method method1 = c2.getMethod("setName",String.class);
        // 类加载的理解,我set参数李四,最后打出来还是张三,参考图片理解
        method1.invoke(new Person(),"李四");
        Method method2 = c2.getMethod("getName",null);
        System.out.println(method2.invoke(new Person()));
        // 获取字段
        Field f1 = c2.getDeclaredField("name");
        Field f2[] = c2.getFields();//获取权限为public的参数
        Field f3[] = c2.getDeclaredFields();//获取所有的参数
        System.out.println(f1);

        System.out.println("============================");
        for (int i = 0; i < f3.length ; i++) {
            System.out.println(f3[i]);
        }
    }
}

class Test{
    public void fun1(){
        System.out.println("method f1 running");
    }
    public void fun2(String str){
        System.out.println("method f1 running args:"+str);
    }
   }
class Person{
    public String name = "张三";
    private int age = 18;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

参考图片
在这里插入图片描述

反射创建对象

public class Test04 {
    public static void main(String[] args) throws Exception{
        Class c1 = Class.forName("User");
        // 无参的构造器,构造方法
        Constructor constructor1 = c1.getConstructor();
        User user1 = (User)constructor1.newInstance();
        System.out.println(user1.toString());
        // 有参的构造器,构造方法
        Constructor constructor2 = c1.getConstructor(String.class,String.class);
        //constructor2.setAccessible(true);//关闭权限检查,提升性能
        User user2 = (User)constructor2.newInstance("张三","123456");
        System.out.println(user2.toString());
    }
}
class User{
    public String username;
    public String password;
    public String getUsername() {
        return username;
    }
    public User() {

    }
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public void setUsername(String username) {
        this.username = username;
    }
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

反射操作注解

public class Test05 {
    public static void main(String[] args) throws  Exception{
        Class c1 = Class.forName("MyUser");
        Annotation annotations[] = c1.getAnnotations();

        TableUser userAnno = (TableUser) c1.getAnnotation(TableUser.class);
        String value = userAnno.value();
        System.out.printf(value);
        // 获得类指定的注解
        Field id = c1.getDeclaredField("id");
        FieldUser fieldAnno = (FieldUser) id.getAnnotation(FieldUser.class);
        String columName = fieldAnno.columName();
        String type = fieldAnno.type();
        int length = fieldAnno.length();
        System.out.printf("%s %s %d",columName,type,length);
    }
}
@TableUser("user")
class MyUser{
    @FieldUser(columName = "db_id",type = "varchar",length = 64)
    public  String id;
    @FieldUser(columName = "db_age",type = "number",length = 3)
    public int age;
}

// 类的注解
@Target(value = {ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@interface TableUser{
    String value();
}
// 属性的注解
@Target(value = {ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
@interface FieldUser{
    String columName();
    String type();
    int length();
}

练习

注解操作数据库示例
效果如图
在这里插入图片描述
在这里插入图片描述

项目地址:
https://github.com/13884566853/Java-test/tree/main/annotation-test
补充
从 Java 7 开始,额外添加了 3 个注解:

@SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告。
@FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口。
@Repeatable - Java 8 开始支持,标识某注解可以在同一个声明上使用多次。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值