Java反射(Reflect) 框架设计的灵魂

框架:半成品软件,可以在框架上开发软件,简化代码

反射机制

将类的各个组成部分封装为其他对象,这就是反射机制
在这里插入图片描述

  • 第一部分Source源代码阶段:源代码对象中有变量构造方法成员方法等内容。(代码->字节码文件)
  • 第二部分Class对象阶段,把不同的部分封装成对象。 (加载入内存)封装成Field[]、Constructor[]、Method[]三个数组对象
  • 第三部分运行阶段:才是声明对象。

反射好处

  • 在程序的执行中操作第二部分的这些对象

使用IDEA会自动弹出该对象的方法,是因为IDEA通过反射机制将对象的字节码文件加载入内存,获取了所有的方法数组Method[],并进行打印提示。
在这里插入图片描述

  • 可以解耦,提高程序的可扩展性
获取第二阶段字节码对象Class的方式

三个阶段,三种不同获取方式

  • 第一阶段:Class.forName("全类名“):将字节码对象加载进内存返回Class对象。多用于配置文件,将类名定义在配置文件中。
  • 第二阶段:通过类名的属性获取类名.Class。多用于传参
  • 第三阶段:对象.getClass()
public static void main(String[] args) throws ClassNotFoundException {
        //1.静态方法forName获取
        Class<?> c1 = Class.forName("object.Person");
        System.out.println(c1);
        //2.类名获取
        Class<Person> c2 = Person.class;
        System.out.println(c2);
        //3.对象获取
        Person p = new Person();
        Class c3 = p.getClass();
        System.out.println(p.getClass());

        System.out.println(c1==c2);
        System.out.println(c1==c3);
    }
//输出
class object.Person
class object.Person
class object.Person
true
true

两个true表示三个对象相同,同一个字节码文件(*.class)再一次执行过程中,只会被加载一次,不同方式获取的Class对象相同。


Field:成员变量

getField 只能获取用public修饰的变量
getDeclaredMethod 获取所有的变量

//获取Person的Class对象
Class personClass = Person.class;
Field f = personClass.getField("name");
//获取name的值
Person p = new Person();//person中有变量 name
Object value = f.get(name);
System.out.println(value);//可以打印出变量name的值
f.set(p,"张三");//改变对象变量
//假设age是私有变量
Field f = personClass.getDeclaredField(age);
//忽略访问权限修饰符
f.setAccessible(true);//暴力反射
f.get(p);//获取年龄
f.set(p,20);//只是age变量的field,所以直接设置age变量

获取到变量后不是特指哪个具体对象的变量,而是声明对象后,在通过变量获取对象的具体变量值。

反射可以获取所有类型变量,并且改变变量通过fieldsetAccessible(true)方法忽略访问权限修饰符安全检查。
获取成员变量之后的操作:

  • 设置值Field中的set()方法
  • 获取值Field中的get()方法

构造方法constructor
  • 用来构造该字节码文件中的对象
Class pClass= Person.class;
//无参构造器
Constructor con1=pClass.getConstructor();
System.out.println(con1);
//输出  public object.Person()


//有参构造器
Constructor con2=pClass.getConstructor(String.class,int.class,int.class);
System.out.println(con2);
//输出  public object.Person(java.lang.String,int,int)
  • 使用constructor的方法创建对象
Object person=con2.newInstance("a",10,100);
System.out.println(person);

//输出object.Person{name='a', age=10, weight=100}
Method成员方法

获取单个方法

Class<Person> personClass = Person.class;

Method getName = personClass.getMethod("getName");

//创建空对象返回 null,传入参数返回参数
Person p =new Person();
//调用方法需要传入 对象和参数
Object name= getName.invoke(p);
System.out.println(name);
//输出null

获取所有方法

Method[] methods = personClass.getMethods();
    for (Method method : methods) {
        System.out.println(method);
    }

输出: 获取所有方法包括 自己写的方法 和继承的父类Object类的所有方法

public java.lang.String object.Person.toString()
public java.lang.String object.Person.getName()
public void object.Person.setName(java.lang.String)
public int object.Person.getAge()
public void object.Person.setAge(int)
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值