java的泛型--注解--反射(下)

144 阅读5分钟

元注解

使用在注解上的注解就是元注解。

@Target:作用:告诉该注解使用的范围,默认是所有位置都可使用

TYPE可以使用在类上

FIELD可以使用在属性上

METHOD使用在方法上

PARAMETER使用在方法参数上

CONSTRUCTOR使用在构造方法上

@Retention:作用:该注解什么时候有效,默认:SOURCE

SOURCE:源码时有效

CLASS:字节码时有效

RUNTIME:运行时有效。【采用的最多】

@Documented:作用:在代码生成api文档时是否存在该注解

image.png

自定义注解的高级

我们发现我们之前使用@GetMapping注解时可以有属性值,我们自定义注解如何赋值?

格式:

@interface 注解名{

数据类型 属性名();

}

数据类型可以是哪些类型?

数据类型可以是基本数据类型,字符串类型,枚举类型,注解类型,数组类型

@Target(ElementType.TYPE)
public @interface My {
    int age() ; //基本数据类型
    String name(); //字符串类型
    MyEnum address(); //枚举类型
    My1 my1(); //注解类型
    int[] ages(); //数组类型
    String[] names();
    MyEnum[] addresss();
    My[] mys();
}

如果属性定义好之后,使用该注解需要指定属性的值。

//如果属性为数组类型,给数组类型赋值时如果只有一个值那么可以省略{}
//如果该注解中只使用value属性,那么value属性名可以省略。

@My(age = 15,name="成俊杰",address = MyEnum.BEIJING,my1 = @My1,ages = {15,20})

@My1(value="np",name="cjj")
public class My3 {

}

反射

反射它是框架设计的灵魂。

框架: 它就是一个半成品,客户可以引入该框架,在框架的基础上填写自己的业务代码。提高开发效率。 比如: springmvc mybatis框架 。

反射;它就是把类中成员封装到其他类对象的形式。再通过该对象可以获取成员的信息。

image.png

获取Class类的反射类的方式

获取Class反射类有三种方式:

第一种:Class.forName("类的全路径")

第二种:类.class

第三种:对象名.getClass

public class Test05 {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种方式
        Class<?> a = Class.forName("demo05.Student");
        //第二种
        Class<Student> b = Student.class;
        //第三种
        Student student = new Student();
        Student student1 = new Student();
        Class<? extends Student> c = student.getClass();
        Class<? extends Student> c1 = student1.getClass();
        //比较对象的引用地址,结果全部为true
        System.out.println(a==b);
        System.out.println(a==c);
        System.out.println(b==c);
        System.out.println(c==c1);
    }
}

class Student{
    String name;
    int age;
}

在Java中,每个类都有一个唯一的Class对象,表示该类的类型。在第三种方式中,我们通过实例化一个对象来获取该对象的Class对象,因为每个实例化的对象都属于该类的类型,所以这两个对象的Class对象是相同的,因此c和c1的引用地址也相同。

通过反射类获得对应的类对象

格式:反射对象.newInstance()

image.png

通过反射类获取属性类对象

获取本类中指定的属性对象:

反射类.getDeclaredField("属性名")

获取本类中所有的属性对象:

反射类.getDeclaredFields()

获取本类以及父类中所有public属性对象

反射类.getFields()

获取本类以及父类中指定的public对象

反射类.getField("属性名")

public class Test {
    public static void main(String[] args) throws Exception {
        Class<Student> stu = Student.class;
        //获取本类中指定的属性对象
        Field name = stu.getDeclaredField("name");
        System.out.println(name);
        //获取本类中所有的属性对象
        Field[] names = stu.getDeclaredFields();
        System.out.println(Arrays.asList(names));
        //获取本类以及父类中public属性对象
        Field[] fields = stu.getFields();
        System.out.println(Arrays.asList(fields));
        //获取本类以及父类中指定的public对象
        Field name1 = stu.getField("age");
        System.out.println(name1);
    }
}

class Teacher{
    private String name;
    public int age;
}
class Student extends Teacher{
  private String name;
  public int age;
}

Field类中常见的方法

setAccessible(true)//设置可以访问私有访问权限

set(object,value)

Class<Student> stu = Student.class;
//通过反射类获得对象的类对象
Student student = stu.newInstance();
//获取本类中指定的属性对象
Field name = stu.getDeclaredField("name");
System.out.println(name);
//设置可以访问私有访问权限
name.setAccessible(true);
name.set(student,"cjj");
System.out.println(student);

通过反射类获取方法类对象

获取本类以及父类中的所有public方法

反射类.getMethods()

获取本类以及父类中的指定public方法

反射类.getMethod("方法名",参数类型)

获取本类中指定的方法

反射类.getDeclaredMethod(方法名,参数类习性)

获取本类中的所有方法

反射类.getDeclaredMethods()

获取本类中指定的方法,有参就需要加上参数类型

Method select = student.getDeclaredMethod("select",int.class)

public class Test {
    public static void main(String[] args) throws Exception {
        Class<Student> student = Student.class;
        Student student1 = student.newInstance();
        //获取本类以及父类中的所有方法
         Method[] methods = student.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

    }
}
class Student{
    private String name;
    public int age;
    public void select(){
        System.out.println("查询所有学生");
    }
}

Method类中常见的方法

invoke 运行指定的方法

public class Test {
    public static void main(String[] args) throws Exception {
        Class<Student> student = Student.class;
        Student student1 = student.newInstance();
        //获取本类中指定的方法
        Method select = student.getDeclaredMethod("select",int.class);
        //运行该方法
        Object invoke = select.invoke(student1, 10);
        System.out.println(invoke);
    }
}
class Student{
    private String name;
    public int age;
    public String select(int i){
        System.out.println("查询所有学生");
        return ""+i;
    }
}

通过反射类获取构造方法对象

获取本类以及父类中指定的public构造方法

反射类.getConstructor(有参就加上类型)

获取本类以及父类中所有的public构造方法

反射类.getConstructors()

获取本类中所有的构造方法

反射类.getDeclaredConstructors()

获取本类中指定的构造方法

反射类.getDeclaredConstructor(有参就加上类型)

public class Test {
    public static void main(String[] args) throws Exception {
        //得到反射类对象
        Class<Student> student = Student.class;
        //getConstructor()获取无参构造函数
        Constructor<Student> constructor = student.getConstructor();
        //通过无参构造函数获取到相应的实例对象
        Student student1 = constructor.newInstance();
        System.out.println(student1);

        //getConstructor()获取有参构造函数
        Constructor<Student> constructor1 = student.getConstructor(String.class, int.class);
        //通过有参构造函数获取到相应的实例对象,并赋值
        Student student2 = constructor1.newInstance("cjj",21);
        System.out.println(student2);
    }
}

class Student{
    private String name;
    public int age;

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

通过类反射获取类上的注解

获取本类以及父类上的所有注解

反射类.getAnnotations()

获取本类以及父类上的指定注解

反射类.getAnnotation(注解名.class)

获取本类上的指定注解

反射类.getDeclaredAnnotation(注解名.class)

获取本类上的所有注解

反射类.getDeclaredAnnotations()

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student.class;
        Annotation[] declaredAnnotations = student.getAnnotations();//拿到本类以及父类的所有注解
        System.out.println(Arrays.asList(declaredAnnotations));
    }
}

@ZuJie("cjj")
class Student{

}
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interface ZuJie{
    String value();
}

通过注解对象操作注解中相关的属性

注解反射对象.注解属性名 //拿到注解中指定属性的值

public class Test {
    public static void main(String[] args) {
        Class<Student> student = Student.class;
         ZuJie declaredAnnotation = student.getDeclaredAnnotation(ZuJie.class);
         String value = declaredAnnotation.value();//拿到注解里面的值
        System.out.println(value);
    }
}

@ZuJie("cjj")
class Student{

}
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interface ZuJie{
    String value();
}