框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码。
开发框架需要反射,使用框架并不需要反射
java代码经历的三个阶段
反射
将类的各个组成部分封装成其他对象,这就是反射机制
好处:
1.程序运行过程中,操纵这些对象
例如String str = "abc";
之所以str能使用那么多方法,就是在定义字符串后,会把字符串字节码文件加载进内存(第一阶段),内存中的class类对象(第二阶段)把所有方法都抽取出来,封装成Method对象,放在Method[]数组中。
2.可以解耦,提高程序的可扩展性
获取class对象的方式
public static void main(String[] args) throws Exception {
//1.Class.forName("全类名")
Class<?> cls1 = Class.forName("com.company.DemoRe.Person1");
//2.类名.class
Class<Person1> cls2 = Person1.class;
//3.对象.getClass()
Person1 p = new Person1();
Class<? extends Person1> cls3 = p.getClass();
System.out.println(cls1 == cls2);
System.out.println(cls2 == cls3);
}
output:
class com.company.DemoRe.Person1
class com.company.DemoRe.Person1
class com.company.DemoRe.Person1
true
true
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论什么方式来获取的class对象都是同一个
Class对象功能:
获取功能:
1.获取成员变量们
Field[] getFields():获取所有**public修饰**的成员变量
Field[] getField(String name):获取指定名称的public修饰成员变量
Field[] getDeclaredFields():获取**所有**成员变量
Field[] getDeclaredField(String name):获取所有指定名称的成员变量,但对于非public修饰的,需要暴力反射
2.获取构造方法们
Constructor<?>[] getConstructors()
Constructor<T> getConstructor(类<?... parameterTypes)
//下列两个需要暴力反射
Constructor<T> getDeclaredConstructors(类<?... parameterTypes)
Constructor<?>[] getDeclaredConstructors()
3.获取成员方法们
Method[] getMethods():所有的public修饰的方法,除了看到的,还有一些Object类中的方法
Method getMethods(String name, 类<?>... parameterTypes)
//下列两个需要暴力反射
Method[] getDeclaredMethods()
Method getDeclaredMethods(String name, 类<?>... parameterTypes)
public static void main(String[] args) throws Exception {
//0.获取Person的class对象
Class personclass = Person.class;
//Field[] getFields()
Field[] fields = personclass.getFields();
for (Field field : fields) {
System.out.println(field);
}
//Field getField(String name)
Field abs = personclass.getField("a");
//获取成员变量a的值
Person p = new Person();
Object value = abs.get(p);
System.out.println(value);
//设置a的值
abs.set(p, "张三");
System.out.println(p);
}
Filed对象功能:
public static void main(String[] args) throws Exception {
//0.获取Person的class对象
Class personclass = Person.class;
Person p = new Person();
Field d = personclass.getDeclaredField("d");
//访问权限不是public修饰的变量时,访问之前
//忽略访问权限修饰符的安全检查
//此语句也称暴力反射
d.setAccessible(true);
System.out.println(d.get(p));
}
案例
写一个框架,可以帮我们创建任意类的对象,并执行其中任意方法
步骤:
1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2.在程序中加载读取配置文件
3.使用反射技术来加载类文件进内存
4.创建对象
5.执行方法
配置文件:
定义配置文件中需要执行的方法
public static void main(String[] args) throws Exception {
//可以创建任意类的对象,可以执行任意方法
/*
前提:不能改变该类的任何代码,可以创建任意类对象,可以执行任意方法
*/
Student stu = new Student();
stu.sleep();
//反射完成
//1.加载配置文件
//1.1创建Properties对象
Properties pro = new Properties();
//1.2加载配置文件,转换为一个集合(双列map集合)
//1.2.1获取class目录下配置文件
ClassLoader classLoader = ReflectT.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("pro.properties");
pro.load(is);
//2.获取配置文件中定义的数据
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
//3.加载该类进内存
Class cls = Class.forName(className);
//4.创建对象
Object obj = cls.newInstance();
//5.获取对象方法
Method method = cls.getMethod(methodName);
//6.执行方法
method.invoke(obj);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。