1.什么是动态语言?
程序运行时,可以改变程序的结构或者变量类型;如Python,javaScript
function(){
var s="var a=3;var b=4;" evals(s);
}
在执行javascript代码的的过程中,可以改变变量的值或插入语句改变结构。
但Java,c 并不是动态的语言
不过我们可以利用反射的机制,字节码的操作等获得动态语言的特性,使得Java的编程更加灵活。
2.反射(reflection)
----程序已经运行,但依然可以加载,探知使用编译期间完全未知的类
----在程序运行的时候,可以只根据类的名称,来动态加载一个类。
对于任意一个已经加载的类,我们都能知道它的所有属性和方法,对于任意一个对象,我们都能调用它的方法和属性。
----Class clz = Class.forName("包名.类名“)
-----加载完类之后,会在堆的内存中产生一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整的结构信息,通过这个对象,
我们可以看到类的结构信息,它就像一面镜子,所以称之为反射。
2.简单的实例
通过反射。User类的结构信息就会被保存到clz对象中。
另外获取Class对象的方法
1.类名.class() 如(int.class User.class)
2.对象名.getClass()
3.反射的作用
--动态加载类,获取类的(属性,方法)
Class clz = Class.forName("包名.类名“)
--动态构造对象
User u = clz.getDeclaredsConstructor ( "形参类型.class"....).newInstance();
--动态调用类的任意方法,构造器
Methods []arr = clz.getDeclaredtMethods()(获得所有方法)
Methods method = clz.getDeclaredMethods("方法名", "方法的形参类型.class")
Constructor [] arr = clz.getDeclaredConstructors()(获得所有的构造器)
Constructor constructor = clz.getDeclaredsConstructor ( "形参类型.class"....)
--动态调用处理属性
Fileds[] array = clz.getFields();(只能获得Publicb属性的变量)
Fileds[] array = clz.getDeclaredFields()(获得所有属性)
Filed field = clz.getDeclaredFields("指定名称的属性")
--动态获取泛型信息
--处理注解
4.实例
package com.ljl.reflection;
import java.lang.reflect.Method;
public class ReflectionTest1 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Class clz = Class.forName("com.ljl.reflection.User");
System.out.println(clz);
//通过反射构造对象
User u1 = (User) clz.getConstructor().newInstance();
System.out.println(u1);
//通反射API调用普通方法
Method method1 = clz.getDeclaredMethod("setId", int.class);
method1.invoke(u1, 001);
Method method2 = clz.getDeclaredMethod("setName", String.class);
method2.invoke(u1, "panda");
//u1.setId(001);u1.setName("panda");相同
System.out.println(u1);
//通过反射Api操作属性
java.lang.reflect.Field f = clz.getDeclaredField("id");
//若属性私有,不能操作,将会报错。
//设置:不做安全检查
f.setAccessible(true);
f.set(u1, 002);
System.out.println(u1);
}
}
结果