java反射和注解

发布于:2024-07-03 ⋅ 阅读:(14) ⋅ 点赞:(0)

反射

获取class对象的三种方法

①:Class.forName("全类名");
②:类名.class
③:对象.getclass();

代码样例

package com.ithema;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种方式
        //最为常用
        Class aClass1 = Class.forName("com.ithema.student");
        System.out.println(aClass1);

        //第二种方式
        //一般更多作为参数传递传递
        Class aClass2 = student.class;
        System.out.println(aClass2);

        //第三种方式
        //当有了这个类的对象时才可以使用
        student s=new student();
        Class aClass3 = s.getClass();
        System.out.println(aClass3);

    }
}

 利用反射获取构造方法


代码样例

package ithema;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //1.获取字节码文件对象
        Class aClass1 = Class.forName("ithema.student");
        
        //2.获取构造方法
        //获取public修饰的构造方法
//        Constructor[] cons = aClass1.getConstructors();
//        for (Constructor con : cons) {
//            System.out.println(con);
//        }

        //获取所有的构造方法
//        Constructor[] cons2 = aClass1.getDeclaredConstructors();
//        for (Constructor con : cons2) {
//            System.out.println(con);
//        }

        //获取单个的构造方法
//        Constructor con1 = aClass1.getDeclaredConstructor();
//        System.out.println(con1);
//
//        Constructor con2 = aClass1.getDeclaredConstructor(String.class);
//        System.out.println(con2);
//
//        Constructor con3 = aClass1.getDeclaredConstructor(int.class);
//        System.out.println(con3);

        Constructor con4 = aClass1.getDeclaredConstructor(String.class, int.class);
        System.out.println(con4);

        //获得权限修饰符
        int modifiers = con4.getModifiers();
        System.out.println(modifiers);

        //得到构造方法所有的参数类型
        Parameter[] parameters = con4.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        //通过反射得到的构造方法创建对象

        //暴力反射:临时取消权限校验
        con4.setAccessible(true);
        student stu = (student) con4.newInstance("张三", 23);
        System.out.println(stu);
    }
}

里面的学生类对象代码:

package ithema;

public class student {
    String name;
    int age;

    public student() {
    }

    public student(String name) {
        this.name = name;
    }

    protected student(int age) {
        this.age = age;
    }

    private student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

利用反射获取成员变量


 代码样例
 

package adsads;

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //第一种方式
        //最为常用
        Class aClass1 = Class.forName("adsads.student");

        //获取所有成员变量
//        Field[] fields = aClass1.getDeclaredFields();
//        for (Field field : fields) {
//            System.out.println(field);
//        }

        //获取单个成员变量
        Field name = aClass1.getDeclaredField("name");
        System.out.println(name);

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

        //获取成员变量的名字
        String n=name.getName();
        System.out.println(n);

        //获取成员变量的数据类型
        Class<?> type = name.getType();
        System.out.println(type);

        //获取成员变量记录的值
        student s=new student("张三",32,"男");
        name.setAccessible(true);
        String value =(String) name.get(s);
        System.out.println(value);
        //修改对象里面记录的值
        name.set(s,"list");
        System.out.println(s);
    }
}

里面的学生类对象代码:
 

package adsads;

public class student {
    private String name;
    private int age;

    public String gender;

    public student() {
    }

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

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

利用反射获取成员方法

package ads;

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

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //第一种方式
        //最为常用
        Class aClass1 = Class.forName("ads.student");

        //获取里面所有的方法对象(包含父类公共的)
//        Method[] methods = aClass1.getMethods();
//        for (Method method : methods) {
//            System.out.println(method);
//        }

        //获取里面所有的方法对象(不包含父类,但是可以获取本类中私有的)
//        Method[] methods1 = aClass1.getDeclaredMethods();
//        for (Method method : methods1) {
//            System.out.println(method);
//        }

        //获取指定的单一方法
        Method m = aClass1.getDeclaredMethod("eat", String.class);
        System.out.println(m);

        //获取方法的修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);

        //获取方法的名字
        String name = m.getName();
        System.out.println(name);

        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }

        //获取方法抛出的异常
        Class[] exceptionTypes = m.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //方法运行
        student s=new student();
        m.setAccessible(true);
        //参数1:s 表示方法的调用者
        //参数2:汉堡包 表示调用方法的时候传递的实际参数
        m.invoke(s,"汉堡包");
    }
}

里面的学生类对象代码:
 

package ads;

import java.io.IOException;

public class student {
    private String name;
    private int age;

    public student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public void sleep(){
        System.out.println("睡觉");
    }
    private void eat(String something)throws IOException ,NullPointerException{
        System.out.println("在吃"+something);
    }
}

反射的作用

获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑

结合配置文件,动态的创建对象并调用方法

 注解

就是Java代码里的特殊标记,比如:@Override、@Test等,作用是:让其他程序根据注解信息来决定怎么执行该程序。

注意:注解可以用在类上、构造器上、方法上、成员变量上、参数上、等位置处。

 自定义注解

 

 注解的原理

 元注解

修饰注解的注解

 

 

 注解的解析

什么是注解的解析?

就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来

如何解析注解?

指导思想:要解析谁上面的注解,就应该先拿到谁。

比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解

比如要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析

其上面的注解。

Class、Method、Field,Constructor、都实现了AnnotatedElement接口,它们都拥有解析注解的能力。

类上面注解的解析

 方法上面的解析

 

注解的作用:如可以用自定义注解来进行实现执行加了注解的方法,不执行不加注解的方法