Java反射机制

反射机制可以帮助我们在代码运行过程中,通过将字节码class文件添加到内存中,从而获取对象
开篇先放完整测试代码

package org.fssx;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class App {
    public static void main( String[] args ) {
        try {
            Class cls = Class.forName("org.fssx.Person");
            System.out.println("获取所有的公开构造函数");
            Constructor [] constructors1 = cls.getConstructors();
            for (Constructor c:constructors1){
                System.out.println(c.toString());
            }
            System.out.println("获取所有的构造函数(包括非公开)");
            Constructor [] constructors2 = cls.getDeclaredConstructors();
            for (Constructor c:constructors2){
                System.out.println(c.toString());
            }
            System.out.println("获取指定参数的构造函数");
            Constructor constructor = cls.getConstructor(String.class,int.class);
            System.out.println(cls.toString());
            System.out.println("获取所有的公开方法");
            Method [] methods1 = cls.getMethods();
            for (Method m:methods1){
                System.out.println(m.toString());
            }
            System.out.println("获取所有的方法(包括非公开)");
            Method [] methods2 = cls.getDeclaredMethods();
            for (Method m:methods2){
                System.out.println(m.toString());
            }
            System.out.println("获取所有的公开属性");
            Field [] fields1 = cls.getFields();
            for (Field f:fields1){
                System.out.println(f.toString());
            }
            System.out.println("获取所有的属性(包括非公开)");
            Field [] fields2 = cls.getDeclaredFields();
            for (Field f:fields2){
                System.out.println(f.toString());
            }
            System.out.println("获取指定属性");
            Field field = cls.getField("age");
            System.out.println(field.toString());
            System.out.println("获取指定属性(包括非public)");
            Field field1 = cls.getDeclaredField("name");
            System.out.println(field1.toString());
        } catch (ClassNotFoundException | NoSuchMethodException | NoSuchFieldException | InstantiationException | IllegalAccessException | InvocationTargetException classNotFoundException) {
            System.out.println("ERROR");
        }
    }
}
class Person{
    static{
        System.out.println("Static");
    }
    private String name;
    public int age;
    protected String sex;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    private Person(String name){
        this.name=name;
    }
    private void doSome(){
        System.out.println("doSome");
    }
    public void doOther(String one,int two){
        System.out.println("doOther");
    }
}

获取类有以下几种方式

Class cls = Class.forName("com.fssx.Student");  // 此方法会调用类的static静态代码块

已经引用的情况下获取类

Class cls = Student.clss;

在实例化的情况下获取类

Student student = new Student();
Class cls = student.getClass();

获取类后有以下方法用于获取方法或者属性

// 获取构造函数
System.out.println("获取所有的公开构造函数");
Constructor [] constructors1 = cls.getConstructors();
System.out.println("获取所有的构造函数(包括非public)");
Constructor [] constructors2 = cls.getDeclaredConstructors(); 
System.out.println("获取指定参数的构造函数");
Constructor constructor = cls.getConstructor(String.class,int.class); // 获取指定参数的构造函数

// 获取方法
System.out.println("获取所有的公开方法");
Method [] methods1 = cls.getMethods();
System.out.println("获取所有的方法(包括非公开)");
Method [] methods2 = cls.getDeclaredMethods();
System.out.println("获取指定参数的方法");
Method method = cls.getMethod("doOther", String.class, int.class);
System.out.println("获取指定参数的方法(包括非public)");
Method method1 = cls.getDeclaredMethod("doSome");

//获取所有属性
System.out.println("获取所有的公开属性");
Field [] fields1 = cls.getFields();
System.out.println("获取所有的属性(包括非公开)");
Field [] fields2 = cls.getDeclaredFields();
System.out.println("获取指定属性");
Field field = cls.getField("age");
System.out.println("获取指定属性(包括非public)");
Field field1 = cls.getDeclaredField("name");

// 获取修饰符,通过getModifiers方法获取的是int类型,public是1,private是2,protected是4,static是8,final是16,通过Modifer.toString()可以将int转换为对应的修饰符
System.out.println("获取修饰符");
int resCode = method1.getModifiers();
System.out.println(resCode); // 1
String resModifier = Modifier.toString(resCode);
System.out.println(resModifier); // public

// 获取方法的参数列表
System.out.println("获取方法参数");
Class [] parameterTypes = method1.getParameterTypes();
for(Class clz:parameterTypes){
    System.out.println(clz.toString());
}

// 实例化
System.out.println("实例化");
constructor.setAccessible(true); // 可以调用私有构造函数
Object app = constructor.newInstance("hello", 12); //通过构造函数实例化
method1.setAccessible(true); // 可以调用私有方法
method1.invoke(app,"one",12); // 调用方法,传入参数
field.setAccessible(true); // 可以调用私有属性
field.set(person, 22); // 设置属性值

看着方法好像很多,其实他是有一定规律的
1、在方法名末尾有s的是返回一个数组,没有s的是返回单个构造器。
2、在方法名中加Declared的是返回所有的构造方法,不加Declared的只返回public访问权限的构造器
3、有参数的都是在方法名中没有在结尾处加s的,返回的是指定参数类型的构造器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值