首先我们需要理解动态语言和静态语言
- 动态语言 是一类在运行时可以改变其结构的语言: 例如新的函数、对象、甚至新的代码可以被引进,已有的函数可以被删除或是发生其他结构上的变化。 通俗点说就是在运行时代码可以根据某些条件改变自身结构。 主要动态语言:Object-C,C#,JavaScript,PHP,Python,Erlang。
- 静态语言 与动态语言相对应的,运行时结构不可变的语言就是静态语言。如Java(因为引入了反射机制,Java可以算是准动态语言)、C、C++。
反射机制允许程序在执行期间通过Reflection API取得任何类的内部信息,并能直接操作任意对象内部属性及方法。加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。
Java反射机制提供的功能
1 | //对于给定Person类 |
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
1
2
3
4
5
6Class clazz = Person.class;Class clazz=Person.class;
//1.通过反射,创建Person类的对象
Constructor cons=clazz.getConstructor(String.class,int.class);
Object obj=cons.newInstance("Tom",12);
Person p=(Person)obj;
System.out.println(p.tostring());在运行时判断任意一个类所具有的成员变量和方法
在运行时获取泛型信息
在运行时调用任意一个对象的成员变量和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//通过反射,调用对象指定的属性,方法
//调用成员变量
Field age=clazz.getDeclaredField("age");
age.set(p,10);
System.out.println(p.tostring());
//调用方法
Method show=clazz.getDeclaredMethod("show");
show.invoke(p);
//通过反射调用私有的构造器,方法,属性
Constructor cons1=clazz.getDeclaredConstructor(String.class);
cons1.setAccessible(true);
Person p1=(Person)cons1.newInstance("Jerry");
System.out.println(p1);在运行时处理注解
生成动态代理
关于java.lang.CLass类的理解
- 类的加载过程: 程序经过javac.exe命令以后,会生成一个或多个字节码文件(.class结尾)。 接着我们使用java.exe命令对某个字芦码文件迸行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载。加载到内存中的类, 我们就秋为运行时类,此运行时类,就作为CLass的一个实例。
- 换句话说,CLass的实例就对应着一个运行时类。
- 加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。
获取Class实例的四种方式
1 | //方式一:调用运行时类的属性:.class |
什么时候使用反射构造对象?
在运行时无法确定对象的类型,需要根据动态运行结果去实时调整构造对象的时候,才去使用反射方式。比如在前端发来请求时,根据pattern,通过反射的方式构造。
1 | "system:post:list") ( |