Skip to content

Java反射

反射机制可以在程序运行状态中,对于任何一个类,知道这个类所有的属性和方法,并且可以调用任意方法,访问任意属性。

作用

可以通过反射实现反编译。 通过反射获取类的属性、方法等。 IDE展示类的属性或方法就是实用反射原理实现的。 反射应用最多的地方就是框架,String,Spring MVC,Mybatis等等。

Class对象

JVM将.class文件读取到内存中,就会创建出一个class对象。 java.lang.Class这个类是反射中常用的。 获取Class对象的几种方式。

java
/**
 * 获取.class文件的Class对象
 */
public class ReflectTest01 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*1.通过类的全名来获取类*/
        Class clazz = Class.forName("xyz.intellij.playground.basic.reflect.Dog");
        /*2.实用类的class属性获取*/
        Class clazz1 = Dog.class;
        /*3.通过对象的getClass方法获取*/
        Object  d = new Dog();
        Class clazz2 = d.getClass();
        /*以上三种方式会获得同一个class对象*/
        System.out.println(clazz == clazz2 && clazz2 == clazz1);
    }
}

创建对象

使用反射创建对象

java
import java.util.Date;

/**
 * 使用反射创建对象
 */
public class ReflectMakeNewObject {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        /*使用这个方法就可以将类读取到内存中*/
        Class clazz = Class.forName("xyz.intellij.playground.basic.reflect.Dog");
        Object object = clazz.newInstance();
        System.out.println(object);
        Class clazzo = Class.forName("java.util.Date");
        Object o1 = clazzo.newInstance();
        System.out.println(o1 instanceof Date);
        System.out.println(o1);
    }
}

利用Java的配置文件创建出可以配置的程序

java
import xyz.intellij.playground.basic.io.file.FilePaths;

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

/**
 * 可以通过配置文件来实现可以配置的java程序
 * 再利用反射机制动态的加载配置好的类
 */
public class ReflectIoExample {
    private static final String keyName = "dogClass";
    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        /*读取配置文件,并创建配置类的对象*/
        try (FileReader fileReader = new FileReader(FilePaths.myTestPath + "dog.properties")) {
            Properties properties = new Properties();
            properties.load(fileReader);
            System.out.println(properties.getProperty(keyName));
            System.out.println(Class.forName(properties.getProperty(keyName)));
            System.out.println(Class.forName(properties.getProperty(keyName)).newInstance());
        }
    }
}
dogClass=xyz.intellij.playground.basic.reflect.Dog

获取类中的属性

可以获取属性和简单实现反编译(没有方法)的处理

java
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;

/**
 * 使用反射获取类中的属性
 * 以及反编译类成员变量
 */
public class GetClassProperties {
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = Class.forName("xyz.intellij.playground.basic.reflect.Dog");
        //获取public成员变量数组
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        //获取类中所有的成员变量
        Field[] fields1 = clazz.getDeclaredFields();
        for (int i = 0; i < fields1.length; i++) {
            System.out.println("------");
            /*获取变量名称*/
            System.out.println(fields1[i].getName());
            /*获取访问控制修饰符号的int值*/
            System.out.println(fields1[i].getModifiers());
            /*获取修饰符*/
            System.out.println(Modifier.toString(fields1[i].getModifiers()));
            /*获取成员变量的类型*/
            System.out.println(fields1[i].getType());
            /*带包名*/
            System.out.println(fields1[i].getType().getName());
            /*不带包名*/
            System.out.println(fields1[i].getType().getSimpleName());
            System.out.println(Declass(Date.class));
        }
    }

    /**
     * 反编译类 只包含属性
     * @param c 类的class对象
     * @return 返回类的字符串
     */
    public static String Declass(Class c) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(Modifier.toString(c.getModifiers()));
        /*类开始*/
        stringBuilder.append(" class ");
        stringBuilder.append(c.getSimpleName());
        stringBuilder.append(" ");
        stringBuilder.append("{");
        stringBuilder.append("\n");
        Field[] fields = c.getDeclaredFields();
        /*属性*/
        for(Field field:fields){
            stringBuilder.append("    ");
            stringBuilder.append(Modifier.toString(field.getModifiers()));
            stringBuilder.append(" ");
            stringBuilder.append(field.getType().getSimpleName());
            stringBuilder.append(" ");
            stringBuilder.append(field.getName());
            stringBuilder.append(";");
            stringBuilder.append("\n");
        }
        stringBuilder.append("\n}");
        return stringBuilder.toString();
    }
}

使用反射赋值

java
import java.lang.reflect.Field;

/**
 * 使用反射获取指定属性并为赋值
 */
public class ReflectAssignProperties {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        Class clazz = Class.forName("xyz.intellij.playground.basic.reflect.Dog");
        /*获取dog的name属性*/
        Field field = clazz.getDeclaredField("name");
        Field field1 = clazz.getDeclaredField("age");
        Object o = clazz.newInstance();
        System.out.println(field);
        /*给特定字段赋值*/
        field.set(o,"zhazha");
        /*私有变量不能赋值,没有权限*/
        /*需要从外部打破封装性,这种方式不建议使用*/
        field1.setAccessible(true);
        field1.set(o,"12");
        System.out.println(o);
    }
}

获取类中方法

java
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 使用反射获取类中的方法
 */
public class ReflectMethod {
    public static void main(String[] args) throws ClassNotFoundException {
        Class clazz = Class.forName("xyz.intellij.playground.basic.reflect.Dog");
        getMethod(clazz);
    }

    public static String getMethod(Class clazz) {
        StringBuilder stringBuilder = new StringBuilder();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            /*获取方法修饰符号*/
            stringBuilder.append("    ");
            stringBuilder.append(Modifier.toString(method.getModifiers()));
            stringBuilder.append(" ");
            stringBuilder.append(method.getReturnType().getSimpleName());
            stringBuilder.append(" ");
            stringBuilder.append(method.getName());
            stringBuilder.append("(");
            Class[] prams = method.getParameterTypes();
            for (Class c : prams) {
                stringBuilder.append(c.getSimpleName());
                stringBuilder.append(",");
            }
            for (int i = 0; i < prams.length; i++) {
                Class c = prams[i];
                stringBuilder.append(c.getSimpleName());
                if (i < prams.length - 1)
                    stringBuilder.append(",");
            }
            stringBuilder.append(")");
            stringBuilder.append(";");
            stringBuilder.append("\n");
        }
        return stringBuilder.toString();
    }
}

调用类中的方法

java
/*使用反射调用类中的方法*/
    public static Object runMethod(Class c) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
        Method method = c.getDeclaredMethod("setName",String.class);
        Object o = c.newInstance();
        return method.invoke(o,"dsad");
    }

获取类的构造方法

java
public static void getConstuctor(Class c){
        Constructor[] constructors = c.getDeclaredConstructors();
        for (Constructor c1:constructors){
            System.out.println(Modifier.toString(c1.getModifiers()));
            System.out.println(c1.getName());
            for (Class cf : c1.getParameterTypes()) {
                System.out.println(cf.getSimpleName());
                System.out.println(",");
            }
        }
    }

获取父类和实现的接口

java
/**
 * 获取类的父类和实现的接口
 */
public class ReflectGetParentClass {
    public static void main(String[] args) {
        Class clazz = StringBuffer.class;
        Class parentClass = clazz.getSuperclass();
        System.out.println(parentClass.getName());
            //        获取接口
        Class[] inter = clazz.getInterfaces();
        for (Class i:inter){
            System.out.println(i);
        }
    }
}