注解和反射

一、注解

1 、注解的定义
  • 不是程序本身,可以对程序做出解释
  • 可以被其他程序读取
  • 以@开头,可以附在加载package,class等上面,相当于给他们添加了额外的辅助信息,可以通过反射访问这些元数据
2、内置注解
  • @Override

  • @Deprecated

  • @SuppressWarning

3、元注解
  • 元注解的作用就是负责解释其他注解,java定义了4个标准的meta-annotation类型,他们提供对其他annotation类型做说明。
  • @Target:注解的使用范围(方法、类等)
  • @Retention:需要在什么级别保存该注释信息,用来描述注解的生命周期(source < class < runtime)
  • @Documented:该注解包含在javadoc中
  • @Inherited:说明子类可以继承父类中的该注解
4、自定义注解
  • @interface用来声明一个注解
  • 其中的每一个方法实际上声明了一个配置参数
  • 方法的名称就是参数的名称
  • 返回值类型是参数的类型
  • 可以通过default来声明参数的默认值
  • 如果只有一个参数,命名为value,因为只有value命名,使用注解时,参数名可以省略
  • 注解元素必须要有值
import java.lang.annotation.*;

public class MyAnnotation {
    @FirstAnnotation("")
    public void test(String[] args) {
    }

    @SecondAnnotation(likes = {"apple","banana"})
    public void test2(String[] args) {
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface FirstAnnotation {
    String value();
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface SecondAnnotation {
    int id() default 0;
    String name() default "";
    String[] likes();
}


二、反射

1、定义

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

反射的在实际中的主要应用是:通过反射获取注解对象,各种框架的底层实现都是如此

2、获得class
  • Class本身也是一个类
  • Class对象由系统创建
  • 一个加载的类在JVM中只会一个Class实例
  • 一个Class对象对应的是一个加载到JVM中的.class文件
  • 每个类的实例都会记得自己是由哪个Class实例生成
  • 通过Class可以完整的得到一个类中的所有被加载的结构

(1)Class.forName 静态方法。

前提:知道该类的全路径名

Class clz = Class.forName("java.lang.String");

(2)使用 .class 方法(最安全可靠,程序性能最高)

前提:已知具体的类

Class clz = String.class;

(3)使用类对象的 getClass() 方法。

前提:存在实例对象

String str = new String("Hello");
Class clz = str.getClass();

(4).Type

说明:只适用于内置基本数据类型

Class<Integer> type = Integer.TYPE;
package study;

public class testGetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Person();

        Class c1 = person.getClass();

        Class c2 = Class.forName("study.Person");

        Class<Person> c3 = Person.class;

        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());

        Class<Integer> type = Integer.TYPE;
        System.out.println(type.hashCode());
    }
}

class Person {
    private int id;
    private String name;

    public Person() {
    }

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

3、创建对象
  1. newInstance()调用了无参构造方法

  2. getConstructor.newInstance有参构造方法

  3. invoke 操作属性,操作私有方法和属性时,需要设置method.setAccessible(true)method.setAccessible(true)可以加快反射的速度

package test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestReflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class c = Class.forName("test.Person");

        //无参构造
        Person object = (Person) c.newInstance();
        System.out.println(object);

        //有参构造

        object = (Person) c.getConstructor(int.class, String.class).newInstance(1,"阿萨德");
        System.out.println(object);

        //操作方法
        Method method = c.getDeclaredMethod("setName", String.class);
        method.setAccessible(true);
        method.invoke(object,"小明");
        System.out.println(object);


    }

}

class Person {
    private int id;
    private String name;

    public Person() {

    }

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

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

4、反射注解

获取类注解 [class].getAnnotation([注解.class])

获取方法注解[method].getAnnotation([注解.class])

事例:模拟MybatisPlus实体表映射

package test;

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

/**
 * @author huahua
 * @description 测试类
 * @date 2020/12/24 14:10
 **/
public class ReflectAnnotation {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取类注解
        Class c = Student.class;
        Table_self annotation = (Table_self) c.getAnnotation(Table_self.class);
        System.out.println(annotation.value());

        //获取方法注解
        Field[] declaredFields = c.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Field_self fieldAnnotation = declaredField.getAnnotation(Field_self.class);
            System.out.println(fieldAnnotation);
        }
    }

}

/**
 * @author huahua
 * @description 自定义表名注解
 * @date 2020/12/24 14:08
 **/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table_self {
    String value();
}

/**
 * @author huahua
 * @description 自定义属性注解
 * @date 2020/12/24 14:19
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field_self {
    //字段名
    String name();

    //字段类型
    String type();

    //字段长度
    int length();
}

/**
 * @author huahua
 * @description 实体类
 * @date 2020/12/24 14:08
 **/
@Table_self("student")
class Student {

    @Field_self(name = "id", type = "int", length = 10)
    private int id;
    @Field_self(name = "name", type = "varchar", length = 10)
    private String name;

    public Student() {
    }

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值