反射的一些使应用

通过反射获取类的结构信息(常用方法)

第一组:java.lang.Class类

  1. getName:获取全类名
  2. getSimpleName:获取简单类名
  3. getFields:获取所有public修饰的属性,包含本类以及父类的
  4. getDeclaredFields:获取本类中所有属性
  5. getMethods:获取所有public修饰的方法,包含本类以及父类的
  6. getDeclaredMethods:获取本类中所有方法
  7. getConstructors: 获取本类所有public修饰的构造器
  8. getDeclaredConstructors:获取本类中所有构造器
  9. getPackage:以Package形式返回包信息
  10. getSuperClass:以Class形式返回父类信息
  11. getInterfaces:以Class[形式返回接口信息
  12. getAnnotations:以Annotation[形式返回注解信息

第二组: java.lang.reflect.Field类

  1. getModifiers:以int形式返回修饰符[说明:默认修饰符是0,public是1, private是2,protected是4,static是8, final是16] 如果是组合的则相加 如public static … -> 1+8
  2. getType:以Class形式返回类型
  3. getName:返回属性名

第三组: java.lang.reflect.Method类

  1. getModifiers:以int形式返回修饰符[说明:默认修饰符是0,public是1,private是2,protected是4,static是8, final是16]
  2. getReturnType:以Class形式获取返回类型
  3. getName:返回方法名
  4. getParameterTypes:以Class返回参数类型数组

第四组: java.lang.reflect.Constructor类

  1. getModifiers: 以int形式返回修饰符
  2. getName:返回构造器名(全类名)
  3. getParameterTypes:以Class[返回参数类型数组

例:

package com.z.reflection;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.spec.RSAOtherPrimeInfo;

/**
 * @author 小白
 * @version 1.0
 * 演示如何通过反射获取类的结构信息
 */
public class ReflectionUtils {
    public static void main(String[] args) {

    }
    //第一组方法API
    @Test
    public void api_01() throws ClassNotFoundException {
        //得到Class对象
        Class<?> personCls = Class.forName("com.z.reflection.Person");
        // getName:获取全类名
        System.out.println(personCls.getName());
        // getSimpleName:获取简单类名
        System.out.println(personCls.getSimpleName());
        // getFields:获取所有public修饰的属性,包含本类以及父类的
        Field[] fields = personCls.getFields();
        System.out.println("本类以及父类的属性:");
        for (Field field : fields) {
            System.out.println(field.getName());
        }
        // getDeclaredFields:获取本类中所有属性
        Field[] declaredFields = personCls.getDeclaredFields();
        System.out.println("本类所有属性:");
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }
        // getMethods:获取所有public修饰的方法,包含本类以及父类的
        Method[] methods = personCls.getMethods();
        System.out.println("本类以及父类的方法:");
        for (Method method : methods) {
            System.out.println(method);
        }
        // getDeclaredMethods:获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        System.out.println("本类的方法:");
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        // getConstructors: 获取本类所有public修饰的构造器
        Constructor<?>[] constructors = personCls.getConstructors();
        System.out.println("本类public构造器:");
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor.getName());
        }
        // getDeclaredConstructors:获取本类中所有构造器
        Constructor<?>[] dc = personCls.getDeclaredConstructors();
        System.out.println("本类所有的构造器:");
        for (Constructor<?> constructor : dc) {
            System.out.println(constructor.getName());
        }
        // getPackage:以Package形式返回包信息
        System.out.println();
        System.out.println(personCls.getPackage());
        // getSuperClass:以Class形式返回父类信息
        System.out.println();
        Class<?> superclass = personCls.getSuperclass();
        System.out.println(superclass);
        // getInterfaces:以Class[形式返回接口信息
        Class<?>[] interfaces = personCls.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("接口信息:" + anInterface);
        }
        // getAnnotations:以Annotation[形式返回注解信息
        Annotation[] annotations = personCls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解信息:" + annotation);
        }
    }

    @Test
    public void api_02() throws ClassNotFoundException {
        //第二组方法API
        Class<?> personCls = Class.forName("com.z.reflection.Person");
        Field[] declaredFields = personCls.getDeclaredFields();
        System.out.println("本类中所有属性:");
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName()
            + " 该属性的修饰符值:" + declaredField.getModifiers()
            + " 该属性的类型:" + declaredField.getType());
        }

        //第三组方法API
        Method[] declaredMethods = personCls.getDeclaredMethods();
        System.out.println("本类以及父类的方法:");
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName()
            + " 该方法的访问修饰符值:" + declaredMethod.getModifiers()
            + " 该方法返回类型:" + declaredMethod.getReturnType());
            //输出当前这个方法的形参数组情况
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            System.out.println("该方法的形参类型:");
            for (Class<?> parameterType : parameterTypes) {
                System.out.println(parameterType);
            }
        }
        //第四组......
    }
}

class A{
    public String hobby;

    public A(){}

    public void hi(){}
}
interface IA{

}
interface IB{

}
@Deprecated
class Person extends A implements IA, IB{
    public String name;
    protected int age;
    String job;
    private double sal;

    public Person(){}

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

    public void m1(String name, int age, double sal){

    }
    protected String m2(){
        return null;
    }
    void m3(){

    }
    private void m4(){

    }
}

通过反射创建对象

  1. 方式一:调用类中的public修饰的无参构造器工
  2. 方式二:调用类中的指定构造器
  3. Class类相关方法
    i. newlnstance:调用类中的无参构造器,获取对应类的对象
    ii. getConstructor(Class…clazz):根据参数列表,获取对应的public构造器对象
    iii. getDecalaredConstructor(Class…clazz):根据参数列表,获取对应的所有构造器对 象
  4. Constructor类相关方法
    i. setAccessible:暴破(可以使用反射访问private构造器)
    ii. newInstance(Object…obj):调用构造器

例:

package com.z.reflection;

import java.lang.reflect.Constructor;

/**
 * @author 小白
 * @version 1.0
 * 演示通过反射机制创建实例
 */
public class ReflectCreateInstance {
    public static void main(String[] args) throws Exception {
        Class<?> userClass = Class.forName("com.z.reflection.User");
        //通过public的无参构造器创建实例
        Object o = userClass.getConstructor().newInstance();
        System.out.println(o);
        //通过public的有参构造器创建实例
        Constructor<?> constructor = userClass.getConstructor(String.class);
        Object k = constructor.newInstance("k");
        System.out.println(o);
        //通过非public的有参构造器创建实例
        Constructor<?> constructor1 = userClass.getDeclaredConstructor(int.class, String.class);
        constructor1.setAccessible(true);//爆破,可以使用反射访问private构造器
        Object q = constructor1.newInstance(12, "q");
        System.out.println(q);

    }
}
class User{
    private int age = 18;
    private String name = "z";

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

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

输出

User{age=18, name='z'}
User{age=18, name='z'}
User{age=12, name='q'}

通过反射访问类中的成员

  • 访问属性

  1. 根据属性名获取Field对象
    Field f = clazz对象.getDeclaredField(属性名);
    
  2. 暴破:
    f.setAccessible(true);//f是Field
    
  3. 访问
     f.set(o,值);
     syso(f.get(o));
    
  4. 注意:如果是静态属性,则set和get中的参数o,可以写成null

例:

package com.z.reflection;

import java.lang.reflect.Field;

/**
 * @author 小白
 * @version 1.0
 * 演示反射操作属性
 */
public class ReflectAccessProperty {
    public static void main(String[] args) throws Exception {
        //得到Student对象对应的Class对象
        Class<?> stuClass = Class.forName("com.z.reflection.Student");
        //创建对象
        Object o = stuClass.getConstructor().newInstance();
        System.out.println(o.getClass());
        //使用反射得到属性对象
        Field age = stuClass.getField("age");
        age.set(o, 16);//通过反射来操作属性
        System.out.println(o);
        System.out.println(age.get(o));//返回age属性的值
        //静态属性
        Field name = stuClass.getDeclaredField("name");
        name.setAccessible(true);//爆破
       // name.set(o,"k"); //也可
        name.set(null, "k");
        System.out.println(o);
        //System.out.println(name.get(o));//也可
        System.out.println(name.get(null));//获取属性值 要求name为static
    }
}
class Student {
    public int age;
    private static String name;

    public Student(){}

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

输出:

class com.z.reflection.Student
Student{age=16name=null}
16
Student{age=16name=k}
k
  • 访问方法

  1. 根据方法名和参数列表获取Method方法对象:

    Method m = clazz.getDeclaredMethod(防方法名,XX.class);

  2. 获取对象:Object o=clazz.newInstance0;

  3. 暴破:m.setAccessible(true);

  4. 访问:Object returnValue = m.invoke(o,实参列表);

  5. 注意:如果是静态方法,则invoke的参数o,可以写成null!

例:

package com.z.reflection;

import java.lang.reflect.Method;

/**
 * @author 小白
 * @version 1.0
 * 演示通过反射调用方法
 */
public class ReflectAccessMethod {
    public static void main(String[] args) throws Exception {
        //得到Boss类对应的Class对象
        Class<?> bossCls = Class.forName("com.z.reflection.Boss");
        //创建对象
        Object o = bossCls.getConstructor().newInstance();
        //调用public的hi方法
        //Method hi = bossCls.getMethod("hi", String.class);//OK
        Method hi = bossCls.getDeclaredMethod("hi", String.class);//OK
        //调用
        hi.invoke(o, "kk");

        //调用private static 方法
        Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
        say.setAccessible(true);
        System.out.println(say.invoke(o, 10, "张三", '男'));
        //因为say方法是static的,还可以这样调用
        System.out.println(say.invoke(null, 12, "李四", '男'));

        //在反射中,如果方法有返回值,统一返回Object,但他的运行类型的方法定义的返回类型一致
        Object reVal = say.invoke(null, 20, "王五", '男');
        System.out.println("reVal 的运行类型 : " + reVal.getClass());
    }
}
class Boss{
    public int age;
    private static String name;

    public Boss() {}

    private static String say(int n, String s, char c){
        return n + " " + s + " " + c;
    }

    public void hi(String s){
        System.out.println("hi " + s);
    }
}

输出:

hi kk
10 张三 男
12 李四 男
reVal 的运行类型 : class java.lang.String
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值