反射(框架的灵魂)

1 篇文章 0 订阅
1 篇文章 0 订阅

什么是反射:
反射就是将类的各个组成部分封装为其他对象,这就是反射机制。

我们在编码时定义的类中包括:成员变量,各种方法,构造方法等信息,利用反射技术可以对这个类进行全面的剖析,将这个类的各个组成部分封装为其他的对象。

获取Class对象的方式

  1. Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
  2. 类名.class:通过类名的属性class获取
  3. 对象.getClass():getClass()方法在Object类中定义着。
  • 结论:
    同一个字节码文件(xxx.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。

(ps:包名不应该出现中文的,此处犯了一个小错误)

package com.lp.reflect反射2;

import com.lp.Domain_reflect2.Person;

public class Reflect {
    /**
     * 获取class三种方式
     */
    public static void main(String[] args) throws Exception {

        //第一种:Class.forName("全类名"),返回Class对象

        Class aClass = Class.forName("com.lp.Domain_reflect2.Person");
        System.out.println(aClass);

        //第二种:类名.Class

        Class personClass = Person.class;
        System.out.println(personClass);


        //第三种:对象名.getClass

        Person p = new Person();
        Class  aClass1 = p.getClass();
        System.out.println(aClass1);

        //结论:无论哪种方法获取的class都是同一种。【字节码文件(.class)】只在内存中加载一次。


        if(aClass == personClass && aClass == aClass1 && personClass == aClass1){
            System.out.println("666");
        }


    }
}
package com.lp.Domain_reflect2;

public class Person {
    private String name;
    private int age;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

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


}


执行结果
在这里插入图片描述

获取类中信息

  • 成员变量,方法,构造方法等
  • 获取这些信息之前先得获取这个类 ,也就是xxx.class

Class对象功能

  • 获取成员变量们

    • Field [ ] getFields() :获取所有public修饰的成员变量
    • Field [ ] getField(String name) 获取指定名称的 public修饰的成员变量
    • Field [ ] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
    • Field [ ] getDeclaredField(String name)
  • 获取构造方法们

    • Constructor [ ] getConstructors()
    • Constructor[ ] getDeclaredConstructors()
  • 获取成员方法们:

    • Method[] getMethods()
    • Method[] getDeclaredMethods()
      注意啦啦啦:(getMethods将返回所有的公共方法,包括从超类继承来的)
  • 获取全类名

    • String getName()

对这些信息的操作

Field:成员变量

1. 设置值
* void set(Object obj, Object value)  
2. 获取值
* get(Object obj) 

Constructor:构造方法

	* 创建对象:
	* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

Method:方法对象

   * 执行方法:
		* Object invoke(Object obj, Object... args)  
	* 获取方法名称:
		* String getName:获取方法名

终于要来代码了
(我这里继续又犯了个小错误,又出现了汉字)

package com.lp.reflect反射;

import com.lp.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;


public class reflect001 {

    public static void main(String[] args) throws Exception {

        Class c = Person.class;    //获取person的class对象



        System.out.println("-------------------获取成员变量---------------------------");

        Field [] fields = c.getFields();   //获取class c 的public修饰的成员变量

        for (Field field: fields  ) {       //for循环 遍历所有的public修饰的成员变量
            System.out.println(field);

        }

        Field d = c.getField("name");  //获取指定名字的成员变量
        System.out.println(d);


        System.out.println("------------------------获取构造函数--------------------------");


        Constructor [] constructors = c.getConstructors();   //获取所有的构造(无参加有参)方法

        for (Constructor constructor:constructors) {
            System.out.println(constructor);
        }

        Constructor constructor = c.getConstructor(String.class, int.class);  //指定参数的构造方法
        System.out.println(constructor);

        **Object person1 = constructor.newInstance("张三", 25); //constructor可以创建新对象
        System.out.println(person1);**

       


        System.out.println("----------------------获取成员方法--------------------------");
        Method[] methods = c.getMethods();
        for (Method methor: methods) {
            System.out.println(methor);
        }

        Method method_eat = c.getMethod("eat");  //获取指定的成员方法
        Person p = new Person();
        method_eat.invoke(p);      // 执行了eat方法
        //System.out.println(method);


        System.out.println("----------------------获取全类名--------------------------");
        String a = c.getName();
        System.out.println(a);
    }

}


在这我又新建了一个Person类,上文的那个Person类不同了

package com.lp;

public class Person {

    public String name;
    public int age;
    public String sex;

    public String a;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }


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

    public Person() {
    }

    public void eat(){
        System.out.println("执行了Person的吃的方法");
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }


}

代码执行结果
在这里插入图片描述
在这里插入图片描述

(转载或引用请标明出处,谢谢)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值