1 反射
1.1 类的加载时机
1. 创建类的实例
2. 类的静态变量,或者为静态变量赋值
3. 类的静态方法
4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
5. 初始化某个类的子类
6. 直接使用java.exe命令来运行某个主类
不用背,就是用到了这个类,这个类就会被加载进内存。
1.2 类的加载过程
三步
1.3 反射概述
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
栈:用来运行方法,每一个方法运行偶读在栈里开辟空间。
堆:用来存放对象。
方法区:保存字节码文件信息(保存类的信息)。
引导类加载器也叫根类加载器。
反射主要操作的是类的Class类型对象。
双亲委派模型
1.4 反射前的准备工作
(插播:
javabean
就是一个类,这个类要满足三个要求。
1. 把属性私有。
2. 提供set/get方法和空参构造。
3. 要实现Serializable 接口。 (可以省略)
这样的类一般放在一个包里,这个包通常叫做bean或pojo或者domain或model。
)
Person类
public class Person {
private String name;
private int age;
public String address;
public String city;
private void hitBeanBean() {
System.out.println("打豆豆");
}
public void sleep(String address, int time) {
System.out.println("在" + address + "睡了" + time + "秒");
}
public void eat() {
System.out.println("吃饭饭");
}
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) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
private Person(int age) {
this.age = age;
}
Person(String name) {
}
}
1.5 Class对象的三种获取方式
一个类的Class类型对象的三种获取方式
1. 通过对象.getClass()方法获取到。
对象名.getClass();
这个getClass方法是Object对象中的,所以任何对象都有这个方法。
2. 类名获取(最简便)
类名.class
3. 通过Class这个类的静态方法进行获取。(最常用,可以把信息放到配置文件中,最灵活)
forName(String className): 根据类名获取到这个类的Class类型的对象。 参数类名必须是全类名(包含包的类名)
任何数据类型都有class属性。包括基本类型
一个类只会创建一个Class类型的对象。
import cn.itcast.bean.Person;
public class Demo01Reflect {
public static void main(String[] args) throws ClassNotFoundException {
//通过对象.getClass()方法获取到。
Person p = new Person();
//调用getClass拿到这个类的Class类型的对象
Class clazz1 = p.getClass();//这个类型是Class,不是Person。只不过这个类中的内容是用来描述Person类的。
System.out.println(clazz1);
//类名获取
Class clazz2 = Person.class;
System.out.println(clazz2);
//通过Class这个类的静态方法进行获取。
Class clazz3 = Class.forName("cn.itcast.bean.Person");
System.out.println(clazz3);
System.out.println(clazz1 == clazz2);//true
}
}
1.6 反射获取构造方法
1.6.1 反射获取空参构造方法并创建对象
反射获取构造方法。
Constructor[] getConstructors(): 获取这个类中的所有的【公共】的构造方法。
Constructor getConstructor(Class... parameterTypes):获取到指定的【公共】的构造方法。 parameterTypes 表示要获取的构造方法的参数列表
Constructor表示构造方法,里面有一个方法,可以完成一些功能。
T newInstance(Object... initargs):通过此构造方法创建一个对象。
参数 initargs:表示调用构造方法时传递的实际参数。
返回值:表示创建的对象。
import java.lang.reflect.Constructor;
import cn.itcast.bean.Person;
public class Demo01Reflect {
public static void main(String[] args) throws Exception {
method2();
}
/*
* Constructor getConstructor(Class... parameterTypes):获取到指定的【公共】的构造方法。 parameterTypes 表示要获取的构造方法的参数列表
* 获取到空参数的构造方法,并且使用空参数的构造方法创建对象。
*/
public static void method2() throws Exception {
//获取这个Person的Class类型的对象
Class clazz = Class.forName("cn.itcast.bean.Person");
//获取指定的构造方法(空参数构造)。
Constructor con = clazz.getConstructor(); //如果获取空参数构造,调用getConstructor方法,参数什么都不需要写。
//此时con表示的就是空参数构造方法
//使用空参构造创建一个对象
Object obj = con.newInstance();//newInstance方法参数表示调用构造方法时传递的实际参数,因为此时调用的是空参数构造,所以不需要传递。
//强转成Person
Person p = (Person)obj;
System.out.println(p.getName() + "--" + p.getAge());
}
/*
* Constructor[] getConstructors(): 获取这个类中的所有的公共的构造方法。
*/
public static void method1() throws Exception {
//获取这个Person类的Class类型的对象
Class clazz = Class.forName("cn.itcast.bean.Person");
//Constructor[] getConstructors(): 获取这个类中的所有的公共的构造方法(public修饰的 )。
Constructor[] cons = clazz.getConstructors();
//遍历数组,打印里面的内容
for(Constructor c : cons) {
System.out.println(c);
}
}
}