什么是框架?
Java框架是一套被设计用来加速和简化Java应用程序开发的代码库。Java框架提供了一组通用的代码模板、库和API,旨在帮助Java开发者快速地构建、测试和部署应用程序,而无需重复编写重复的代码与业务逻辑。
Java框架通常按功能进行分类,主要分为以下几个领域:
- Web应用程序框架,如Spring MVC、Struts和Java Server Faces(JSF)等。
- 持久化框架,如Hibernate、JPA(Java Persistence API)等。
- 国际化框架,如Spring国际化框架。
- 安全框架,如Spring Security、Apache Shiro等。
- 测试框架,如JUnit和TestNG等。
使用Java框架可以帮助Java开发者快速开发高效、可维护的应用程序。
说白了框架就是半成品软件,我们在这个办成品的基础上进行开发。
反射(框架设计的灵魂)
专业术语:Java反射是指在程序运行时动态地获取和操作类的信息,包括类的属性、方法、构造函数等。通过反射,Java程序可以在运行时检查任意一个对象所属的类的信息,并且可以调用该类的方法、访问和修改该类的属性,或者创建该类的对象。反射机制使Java程序可以在运行时动态地加载、扩展和修改类的行为,可以实现很多高级的功能,例如构造泛型实例、动态代理、动态生成代码、框架扩展等。
白话:把类的各个组成部分封装为其他对象,这个过程称为反射机制。
如上图所示,Person.class通过类加载器将各个部分进行封装,这个过程就是反射机制。
1. 获取Class类对象的方式
共有三种方式,对应着上图的三个阶段:
① Class.forName(“全类名”);
- 当你的java代码在 Source源代码阶段 时使用。原理:通过将字节码文件加载进内存,返回Class对象
- 多适用于配置文件,将类名定义在配置文件中。读取文件,加载文件
② 类名.class
- 你的代码已经将字节码文件加载进内存,处于 Class类对象阶段。原理:通过类名的属性class来获取
- 多用于参数的传递
③ 对象.getClass()
- .getClass()这个方法时封装在Object这个类中的,封装在Object类中的方法被所有类继承。
- 多用于对象的字节码文件的获取
示例:
- 创建一个Person类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private int age;
}
- 创建一个测试类
/**
* {@code @ProjectPath} : FanShe_ZhuJie_FanXing
* {@code @Author} : MrLiu
* {@code @Date} : 2023/6/13 16:40
* <
* 获取类对象的三种方式:
* 1.Class.forName("全类名")
* 2.类名.class
* 3.对象.getClass()
* >
*/
public class ReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException {
//1.Class.forName("全类名")
Class<?> aClass1 = Class.forName("com.ly.fanShe.demo01.Person");
System.out.println("aClass1: " + aClass1);
//2.类名.class
Class<Person> aClass2 = Person.class;
System.out.println("aClass2: " + aClass2);
//对象.getClass()
Person person = new Person();
Class<? extends Person> aClass3 = person.getClass();
System.out.println("aClass3: " + aClass3);
//对三个对象进行比较
System.out.println(aClass1 == aClass2);//==比的是对象在内存中的地址
System.out.println(aClass1 == aClass3);
}
}
-结果:
三个对象的对比结果为true,说明:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
2. Class类对象的使用
建议个人通过jdk文档获得帮助。
链接(百度网盘):https://pan.baidu.com/s/1Pl9HUUN1-NgGRH90pdOQGg
提取码:6666
比如:
我想Class对象的功能,就可以这样操作:
- 打开jdk1.8帮助文档
- 在索引上搜索Class
获取功能
- 获取成员变量(们)
- Field getField(String name)
- field.get(类对象):获取成员变量的值。
- field.set(类对象, 值):设置成员变量的值。
- Field[] getFields()
- ===== 以上获取时,只能获得public修饰的 =======
- ===== 以下获取时,不论修饰符,但是要获取private修饰的,请设置 field.setAccessible(true) =======
- Field getDeclaredField(String name)
- field.get(类对象):获取成员变量的值。
- field.set(类对象, 值):设置成员变量的值。
- Field[] getDeclaredFields()
- Field getField(String name)
- 获取构造方法(们)
- Constructor getConstructor(类<?>… parameterTypes)
- constructor.newInstance(类对象的属性值…):创建对象,也可使用无参构造创建对象,如果说你要使用无参创建对象,建议使用 Class类对象.newInstance() 来创建。
- Constructor<?>[] getConstructors()
- ===== 以上获取时,只能获得public修饰的 =======
- ===== 以下获取时,不论修饰符,但是要获取private修饰的,请设置 field.setAccessible(true) =======
- Constructor getDeclaredConstructor(类<?>… parameterTypes)
- 如果你访问的不是public修饰的元素,那么请设置constructor.setAccessible(true)。
- constructor.newInstance(类对象的属性值…):创建对象。
- Constructor<?>[] getDeclaredConstructors()
- Constructor getConstructor(类<?>… parameterTypes)
- 获取成员变量(们)
- Method getMethod(String name, 类<?>… parameterTypes)
- method.invoke(类对象,有参数在此填入):执行对象。
- Methods[] getMethods():获取所有的方法也包括父类。
- ===== 以上获取时,只能获得public修饰的 =======
- ===== 以下获取时,不论修饰符,但是要获取private修饰的,请设置 field.setAccessible(true) =======
- Method getDeclaredMethod(String name, 类<?>… parameterTypes)
- method.invoke(类对象,有参数在此填入):执行对象。
- Methods[] getDeclaredMethods()
- Method getMethod(String name, 类<?>… parameterTypes)
- 获取类名
- String getName() :全类名
- String getSimpleName() :类名
3. 案例
需求:写一个简单的框架,它可以帮我们执行任意类的对象,并且执行其中的任意方法。
具体详情看我发的手写ORM框架。