1、反射出现的背景意义
servlet中并没有主方法既是main方法,因此其每次运行都需要依靠tomcat.而tomcat是用Java写的,tomcat中有主方法,servlet和tomcat中的主方法一结合就可以启动运行了。因此我们可以这样认为只有有主方法的才能自己运行,可以作为一个进程运行。而没有主方法的不能自己运行的只能作为一个线程存在。
tomcat调用servlet运行,但tomcat是如何调用servlet的?servlet也是一个类,其中也能像普通类中定义除了doget(),dopost()外的各种方法。由于servlet定义的名字五花八门,tomcat不知道各个servlet的名字于是更不可能通过new的方式创建servlet对象,那对象中的doget(),dopost()方法也是不能被调用的。
各种编程语言一般都有扫描文件的能力,但即使知道文件路径,那你是如何确定那个.class文件是servlet呢?servlet和普通类一样名字都是可以任意取的。况且也没有相应的语法知道了类文件的
因此依据之前的方式,tomcat是无法获得servlet对象的,更无法调用servlet中的各种方法
为了解决这个问题出现了反射
2、类的生命周期
3、反射机制的作用
1、在运行时判断任意一个对象所属的类
2、在运行时构造任意一个类的对象
3、在运行时的到一个类所具有的成员变量和方法
4、在运行时调用任何一个类所具有的成员变量和方法
5、生成动态代理
4、反射相关的主要类
1、java.lang.Class:代表一个类,Class对象表示某个类加载后在堆中的对象。
2、java.lang.reflect.Method:代表类的方法,Method对象表示某个类的方法
3、java.lang.reflect.Field:代表类的成员变量,Field代表某个类的成员变量
4、java.lang.reflect.Constructor:代表类的构造方法,Constructor表示某个类的构造器
5、Class类的细节
1、Class也是类,因此也继承Object类
2、Class类对象不是new出来的,而是系统创建的。Class类是通过类加载器ClassLoader生成的ClassLoader中有一个loadClass()方法。通过该方法生成某个类的类对象。
- 传统new 对象的方式创建对象
会进入该方法中然后返回类对象
- 反射方式创建对象仍会进入上图所示的方法
3、对于某个类的Class类对象,在内存中只有一份,因为类只加载一次。创建类对象时会加锁,防止多线程环境下生成多个Class类对象
public class Test {
public static void main(String[] args) throws Exception {
Cat cat=new Cat();
Class catClass=Class.forName("com.company.Cat");
}
}
此时若在Class catClass=Class.forName(“com.company.Cat”);处打断点执行的话,就不能进入loadClass方法了,因此Cat类已经在Cat cat=new Cat()语句中执行过一次了,类对象已经加载入内存中了。
4、每个类的实例都会记得自己是由那个Class实例所产生的
5、通过Class对象可以完整的得到一个类的完整结构,通过一系列的API
6、Class对象是存放在堆里的
7、类的字节码二进制数据是放在方法区的,有的地方称为类的元数据。
6、Class类的方法
public class Test {
public static void main(String[] args) throws Exception {
Class<?> catClass=Class.forName("com.company.Cat");
System.out.println(catClass);//显示catClass是那个类的Class对象 运行结果:class com.company.Cat
System.out.println(catClass.getClass());//class java.lang.Class
//2、得到包名
System.out.println(catClass.getPackage().getName());//com.company
//3、得到全类名
System.out.println(catClass.getName());//com.company.Cat
//4、通过类对象创建对象实例
Cat cat=(Cat)catClass.newInstance();
//5、通过反射得到对象的属性(只能获取公有属性)
Field name=catClass.getField("name");
System.out.println(name.get(cat));//发财
//6、通过反射给对象的属性赋值
name.set(cat,"招财");
System.out.println(name.get(cat));//招财
//7、得到对象的所有属性
Field[] fields