【Mark学Java】反射

反射

通过集成开发环境(IDE)创建程序时,可以通过.检查可用的方法,并返回方法名;通过远程方法调用(RMI)允许将一个Java程序对象分布到多台机器上.反射机制为上述功能实现保证.

来看看什么是反射机制.

Java代码在计算机中经历三个阶段:Source源代码阶段,Class类对象阶段,Runtime运行时阶段

在这里插入图片描述
Person类的Java源程序Person.java首先通过javac编译与平台无关的字节码文件Person.class,通过类加载器ClassLoader加载到内存.内存中的Class类对象包含成员变量,构造方法,成员方法. Runtime运行时阶段,通过new Person()创建Person对象.

反射机制,将类中的各个组成部分封装为其他对象,可以在程序运行过程中,操作这些对象,实现解耦,提高程序的可扩展性.

Class类java.lang.reflect类库一起对反射机制进行支持,该类库包含了Field,Method,Constructor类,这些类在JVM运行时创建,用以表示未知类里对应的成员.

获取Class对象的方式:

  • Source源代码阶段: Class.forName("全类名")
    多用于配置文件,将类名定义在配置文件中,读取文件,加载类
  • Class类对象阶段: 通过类名的属性class获取
    多用于参数传递
  • 运行时阶段: 对象.getClass()方法在Object类中定义
    多用于对象的获取字节码方式
    public static void main(String[] args) throws ClassNotFoundException {
        
        Class cls1 = Class.forName("Test.Person");
        System.out.println(cls1);
        
        Class<Person> cls2 = Person.class;
        System.out.println(cls2);
        
        Person person = new Person();
        Class cls3 = person.getClass();
        System.out.println(cls3);
    }

cls1,cls2,cls3是同一个对象.同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个

Class对象功能:
获取功能:
1.获取成员变量
Field[ ] getFields() 获取public修饰的成员变量
Field getField(String name)获取所有成员变量

Field[ ] getDeclaredFields()
Field getDeclaredField(String name)
2.获取构造方法
Constructor<?>[ ] getConstructors()
Constructor<T>[ ] getConstructors(类<?> parameterTypes)

Constructor<?>[ ] getDeclaredConstructors()
Constructor<T>[ ] getDeclaredConstructors(类<?> parameterTypes)
3.获取成员方法
Method[ ] getMethods()
Method getMethod(String name,类<?> parameterTypes)

Method[ ] getDeclaredMethods()
Method getDeclaredMethod(String name,类<?> parameterTypes)
4.获取类名
String getName()

Field成员变量获得全类名
操作
1.设置值
void set(Object obj,Object value)
2.获取值
get(Object obj)
3.忽略权限修饰符的安全检查(暴力反射)
setAccessible(true)

    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Field[] fields = personClass.getFields();
        for (Field field:fields){
            System.out.println(field);
        }
        Field a = personClass.getField("a");
        Person person = new Person();
        Object o = a.get(person);
        System.out.println(o);
        a.set(person,"Mark");
        System.out.println(person);
    }

在这里插入图片描述
Constructor构造方法
创建对象
T newInstance(Object...initargs)
可以使用空参构造器:使用Class对象的newInstance()方法

 public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Constructor constructor =personClass.getConstructor(String.class,int.class);
        //创建对象
        Object obj=constructor.newInstance("张三",23);
        
        Constructor constructor1 =personClass.getConstructor();
        //创建对象
        Object obj1=constructor1.newInstance();
        
        //空参构造器
        Object obj2=PersonClass.newInstance();
    }

Method方法对象
Object invoke(Object obj,Object...args)执行方法
String getName()获取方法名

    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Method eat = personClass.getMethod("eat");
        Person person = new Person();
        eat.invoke(person);
    }
    public static void main(String[] args) throws Exception {
        Class<Person> personClass = Person.class;
        Method[] methods = personClass.getMethods();
        for (Method method:methods){
            System.out.println(method);
        }
    }

在这里插入图片描述
案例
需求:写一个框架,可以帮我们创建任意类的对象,并且执行其中任意方法
实现:1.配置文件 2.反射
步骤:将需要创建的对象的全类名和需要执行的方法定义在配置文件中

    public static void main(String[] args) throws Exception {
        //创建properties
        Properties pro = new Properties();
        //获取class目录下的配置文件
        ClassLoader classLoader = ReflectDemo04.class.getClassLoader();
        //获取配置文件对应的字节流
        InputStream is = classLoader.getResourceAsStream("pro.properties");
        pro.load(is);
        //获取配置文件中定义的数据
        String className = pro.getProperty("className");
        String method = pro.getProperty("methodName");
        //加载该类进内存
        Class cls = Class.forName(className);
        //创建对象
        Constructor constructor = cls.getConstructor();
        Object o = constructor.newInstance();
        //获取对象方法
        Method method1 = cls.getMethod(method);
        //执行方法
        method1.invoke(o);
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值