JAVA中的反射

1.获取Class对象的三种方式
名称解释
通过类名获取类名.class
通过对象获取对象名.getClass()
通过全类名获取Class.forName(全类名)
1.1实例展示
public class Student {
    private int age;
    private String name;
    private String address;
    private double score;

    public Student() {
    }

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

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", score=" + score +
                '}';
    }
}
Class cla = null;
//通过类名
cla = Student.class;
//通过对象获取
cla = (new Student).getClass()
//通过全类名获取
cla = Class.forName("com.xx.xxx.xx")
2.创建实例,判断是否为某个类的实例
方法名功能说明
static Class forName(String name)返回指定类名name的Class对象
Object newInstance()调用缺省构造函数,返回该Class对象的实例
Object newInstance(Object[] args)调用当前格式构造函数,返回该Class对象的一个实例
getName()返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称
Class getSuperClass()返回当前Class对象的父类的Class对象
Class[] getInterface()获取当前Class对象的接口
ClassLoader getClassLoader()返回该类的类加载器
Class getSuperclass()返回表示Class所表示的实体的超类Class
//创建类的实例
Class<?> c = String.class;
Object str = c.newInstance();

//判断是否为某个类的实例
public native boolean isInstance(Object obj);
2.1实例演示
public class jkc {
    public static void main(String[] args) {
        Class<?> c = String.class;
        try {
            Constructor<?> declaredConstructor = c.getConstructor(String.class);
            Object o = null;
            try {
                o = declaredConstructor.newInstance("2333333333");
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            ADC a = new ADC();
            boolean instance = c.isInstance(a);
            System.out.println(o);
            System.out.println(instance);
            String name = reflectionClass.getName();
            System.out.println(name);//Basic.Reflection
            Class<? super Reflection> superclass = reflectionClass.getSuperclass();
            System.out.println(superclass);//class Basic.ADB

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }
}
class ADC{
    public void func(){
        System.out.println("frg");
    }
}
3.ClassLoader
  • 类装载器是用来把(class)装载进JVM的,JVM规范定义了两种类型的类装载器(bootstrap)和用户自定义装载器(user-defined class loader)。JVM在运行时会产生3个类加载器组成的初始化加载器层次接口,如下图所示:

在这里插入图片描述

public class ReflectionTest {
    public static void main(String[] args) {
        //获取一个系统的类加载器(可以获取)
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

        //获取系统加载器的父类加载器(扩展类加载器,可以获取)
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@4b67cf4d

        //获取扩展类的加载器的父类加载器(引导类加载器,不可获取)
        ClassLoader parent1 = parent.getParent();
        System.out.println(parent1);//null

        //获取当前类是由哪个加载器进行加载的(系统里加载器)
        ClassLoader classLoader = ReflectionTest.class.getClassLoader();
        System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2

    }
}


#########################系统类加载器#############################
//调用 getResourceAsStream() 获取类路径下的文件对应的输入流
##系统类加载器可以加载当前项目下面的所有类,如果文件也放在src下面,也可以用类加载器来加载
this.getClass().getClassLoader().getResourceAsStream("test1.txt");
##放在内部文件夹,要写全路径
this.getClass().getClassLoader().getResourceAsStream("com/****/java/reflection/test2.txt");
4.获取方法
4.1获取构造方法
方法名解释
getConstructors()返回运行时类的public构造方法
getDeclaredConstructors()返回运行时类的全部构造方法
getConstructors(Class… paramType)返回运行时类的特定构造方法,且是public
getDeclaredConstructor(Class… paramType)返回运行时类的特定构造方法
Constructor<Person>[] constructors = (Constructor<Person>[]) personClass.getConstructors();
for (Constructor<Person> constructor: constructors){
    System.out.println(constructor);
}
Constructor<Person>[] constructors1 = (Constructor<Person>[]) personClass.getDeclaredConstructors();
for (Constructor<Person> constructor: constructors1){
    System.out.println(constructor);
}

Constructor<Person> constructors2 =  personClass.getConstructor(int.class,String.class);
    System.out.println(constructors2);


Constructor<Person> constructors3 =  personClass.getDeclaredConstructor(int.class);
    System.out.println(constructors3);
4.2获取方法Method
方法解释
getMethods()获取clazz对应类的所有方法,只能获取public,且获取从父类继承的所有方法
getDeclaredMethods()获取所有的方法,包括私有的方法,且只获取当前类
getMethod(“方法名”,Class paramTypes…)获取指定的方法,无参可以不用写,且只能获取public方法
getDeclareMethod(“方法名”,Class paramTypes…)获取指定的方法,无参可以不用写,且只能获取本类的
class AD{
    private void func1(){
        System.out.println("func1");
    }
    protected void func2(){
        System.out.println("func2");
    }
    void func3(){
        System.out.println("func3");
    }
    public void func4(){
        System.out.println("func4");
    }
}
class AC extends AD{
    public void func11(String str){
        System.out.println("func11");
    }
    private void func22(){
        System.out.println("func22");
    }
}
Class<AC> adClass = AC.class;
Method[] methods = adClass.getMethods();
for (Method method: methods){
    System.out.println(method+"========");
}
Method[] methods1 = adClass.getDeclaredMethods();
for (Method method: methods1){
    System.out.println(method+"-----------");
}
Method methods2 = adClass.getMethod("func11",String.class);
System.out.println(methods2+"++++++++++++");

Method methods3 = adClass.getDeclaredMethod("func22");
System.out.println(methods3+"\\\\\\\\\\\\\\\\");
4.2.1获取到方法后,进行操作方法
方法解释
getReturnType()获取方法的返回值类型
getParameterTypes()获取方法的参数列表
getModifiers()返回方法的访问修饰符 0:无修饰符 1:public 2:private 4:protected
getName()获取方法的名称
getExceptioTypes()获取方法的异常信息
Method methods3 = adClass.getDeclaredMethod("func22");
System.out.println(methods3+"\\\\\\\\\\\\\\\\");

Class<?> returnType = methods3.getReturnType();
System.out.println(returnType);//void

Class<?>[] parameterTypes = methods3.getParameterTypes();
for (Object object:parameterTypes){
    System.out.println(object);
}
int modifiers = methods3.getModifiers();
System.out.println(modifiers);//2

Class<?>[] exceptionTypes = methods3.getExceptionTypes();
for (Object exception:exceptionTypes){
    System.out.println(exception);
}
4.2.2获取父类的(私有)方法
class BVC{
    /**
     * 
     * @param obj           某个类的一个对象
     * @param methodName    类的一个方法名称,该方法可能是私有方法,还有可能是该方法在父类中定义的(私有)方法
     * @param args  调用该方法需要传入的参数
     * @return      调用方法后的返回值
     */
    public Object invoke2(Object obj,String methodName,Object ... args) {
        Class[] parameterTypes = new Class[args.length];
        for (int i = 0; i < args.length;i++){
            parameterTypes[i] = args[i].getClass();
        }
        try {
            Method method = getMethod(obj.getClass(),methodName,parameterTypes);
            //私有方法的执行,必须在调用invoke之前加上一句 method.setAccessible(true)
            method.setAccessible(true);
            return method.invoke(obj,args);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
        
    }
    public Method getMethod(Class cla, String methodName,Class ... parameterTypes) throws NoSuchMethodException {
        for (; cla != Object.class; cla = cla.getSuperclass()){
            Method declaredMethod = cla.getDeclaredMethod(methodName, parameterTypes);
            return declaredMethod;
        }
        return null;
        
    }
}
4.2.3获取描述字段 — Field
方法名解释
getDeclaredFields()获取公用和私用的所有字段,但不能获取父类字段
getFields()获取运行时类public修饰的字段,且包括父类的public字段
getDeclaredField(parameterType)获取指定的字段,且不能获取父类的字段
getField(parameterType)获取public修饰的字段,且不包含父类的字段
Field[] declaredFields = adClass.getDeclaredFields();
for (Field field:declaredFields){
    System.out.println(field+"========");
}
Field[] fields = adClass.getFields();
for (Field field:fields){
    System.out.println(field+"-------------");
}
Field frg = adClass.getField("frg");
System.out.println(frg);
Field eff = adClass.getDeclaredField("eff");
System.out.println(eff);
  • field用来描述运行时类的成员变量

    方法名解释
    getModifiers()获取成员变量访问权限修饰符(同上)
    getType()获取成员变量的数据类型
    getName()获取成员变量的名称
    isAnnotationPresent(Class)判断注解是否在当前指代上
    getDeclaredAnnotations()获取直接存在此元素上的所有注解,且不包括父类
    getAnnotations()获取此元素上存在的所有注解
    getDeclaredAnnotation(Class)获取特定的注解
    getAnnotation(Class)获取特定的注解,且包含父类的
    对于private修饰的成员变量,操作前需要调用setAccessible(boolean),值为true表示可以修改,值为false表示不能修改;set(Object object,Types types)修改数据,get(Object)获取参数值
Reflection reflection = reflectionClass.newInstance();
//Reflection reflection = new Reflection();
Field field = reflectionClass.getDeclaredField("num");
field.setAccessible(true);
Object o = field.get(reflection);
System.out.println(o);
field.set(reflection,100);
int modifiers = field.getModifiers();//public static final int PUBLIC           = 0x00000001;
Object o1 = field.get(reflection);
System.out.println(o1);
Class<?> type = field.getType();
System.out.println(type);
System.out.println(modifiers);
String name = reflectionClass.getName();
System.out.println(name);//Basic.Reflection
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值