反射:框架设计的灵魂
- 框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
- 反射:将java代码的各个组成部分封装为其他对象,可以在程序运行过程中操作这些对象,这就是java的反射机制,如下图。
- 反射的好处:
- 可以在程序运行过程中,操作这些对象。
- 可以解耦,提高程序的可扩展性。
- 反射的前提:
- 类必须加载到内存中之后,才能使用反射。(因为加载到内存中,才能生成.class文件)
- 类是用来描述对象的。比如:Person类,Student类(就是class类)。
- 类似于现实生活中的人类。Person类中有心、肝、肺。那么就相当于的Person class类中的成员变量、成员方法、构造方法。
- 反射:使用class文件对象(相当于手术刀)对内存中的类进行解剖,获取这个类中的成员变量、成员方法、构造方法。使用class文件对象(手术刀)解剖的Person类,最后给了专家(类似于)Filed字段、Method方法、Constructor构造方法。
对于任何一个进入到内存中的类,我们都可以使用相同的方式进行解剖。
下面是反射的图解:
下面是类加载器的图解:
获取Class对象的方式(重点)
获取class对象方式 | 作用 | 应用场景 |
---|---|---|
Class.forName(“全类名”) | 通过指定的字符串路径获取 | 多用于配置文件,将类名定义在配置文件中。读取文件,加载类 |
类名.class | 通过类名的属性class获取 | 多用于参数的传递 |
对象.getClass() | 通过对象的getClass()方法获取 | 多用于对象的获取字节码的方式 |
注意:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
- Class文件对象的三种获取方式(总结):
1. 使用Object类中的方法getClass。
2. 使用类名.class。(一般用于获取本类)
3. 使用Class类中的静态方法forName(“全类名( 包名+类名)”)
下面是举例说明:
package com.ccc.demo02Reflect;
import com.ccc.demo03domain.Person;
public class Demo01Reflect {
public static void main(String[] args) throws ClassNotFoundException {
//1.使用Object类中的方法getClass
Person p = new Person();
Class c1 = p.getClass();
System.out.println(c1); //class com.ccc.demo03domain.Person
System.out.println("==========================");
//2.使用类名.class
Class c2 = Person.class;
System.out.println(c2); //class com.ccc.demo03domain.Person
System.out.println("===========================");
//3.使用Class类中的静态方法forName("全类名( 包名+类名)")
Class c3 = Class.forName("com.ccc.demo03domain.Person");
System.out.println(c3); //class com.ccc.demo03domain.Person
}
}
Person类:
package com.ccc.demo03domain;
public class Person {
private String name;
private int age;
private String sex;
public Person() {
System.out.println("Person类的空参数构造方法");
}
public Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
System.out.println("Person类的全参数构造方法");
}
private Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person类的私有构造方法");
}
//私有方法
private void method(){
System.out.println("Person类的私有方法");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
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;
}
}