类的加载器
介绍:
BootStrapClassLoader 根类加载器 引导类加载器
并不是由Java语言编写 而是由C++语言编写 主要负责加载核心包下的类ExtClassLoader 扩展类加载器
Java语言编写 主要负责加载扩展包下的类 ext包下AppClassLoader 应用类加载器
Java语言编写 主要负责加载我们写的类 和 第三方工具的类
注意:
三个类加载器之间没有任何集成关系
但是BootStrap是Ext的父加载器
Ext是AppClass的父加载器
双亲委托机制
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
获取一个类的字节码文件对象的三种方式
1.Object类 getClass方法
2.类隐藏的静态的class属性
3.Class类的静态方法 forName(String className)
public class Demo01_GetClass {
public static void main(String[] args) throws ClassNotFoundException {
// 1.Object类的 getClass方法
// Person p = new Person();
// Class c1 = p.getClass();
// System.out.println(c1);
// 2.类隐藏的静态的class属性 包括基本类型
Class c2 = Person.class;
System.out.println(c2);
// System.out.println(c1 == c2);
// 3.Class类的静态方法 forName(String className)
String s = "com.doit.bean.Person";
s = "java.util.ArrayList";
Class c3 = Class.forName(s);
System.out.println(c3);
// System.out.println(c1 == c3);
}
}
java.lang.Class
String getName() 获取类名 带包名
String getSimpleName() 获取不带包名的类名
Class[] getInterfaces() 获取一个类实现的所有接口
public class Demo02_Class {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("com.doit.bean.Person");
//获取带包名的类名
String name = c.getName();
System.out.println(name);
//获取不带包名的类名
String simpleName = c.getSimpleName();
System.out.println(simpleName);
//获取包名
Package p = c.getPackage();
System.out.println(p);
//获取父类
Class superclass = c.getSuperclass();
System.out.println(superclass);
//获取一个类实现的所有接口
Class[] arr = c.getInterfaces();
for (Class aClass : arr) {
System.out.println(aClass);
}
}
}
反射的概念
反射:将java代码的各个组成部分封装为其他对象,可以在程序运行过程中操作这些对象.
好处
可以在程序运行过程中,操作这些对象。
可以解耦,提高程序的可扩展性
Class类获取空参的方法:
Constructor[] getConstructors() 获取所有公共的空参构造
Constructor[] getConstructors() 获取空参构造方法
运行空参构造方法
Constructor类
Object newInstance() 运行空参构造 创建对象
获取带参构造的方法:
Constructor getConstructor(Class...paramType) 获取指定的公共的带参构造方法
需要指定参数的数据类型 通过参数的字节码文件对象来指定
如果是String String.class
如果是int int.class运行带参构造方法
Constructor类
Object newInstance(Object...args)
Object...args:运行构造方法需要的实际参数
了解一下暴力反射
获取Person类的私有构造方法并运行(暴力反射)
了解 不推荐使用 破坏了类的封装性 不安全
1.获取字节码文件对象
2.通过字节码文件对象 获取私有构造方法
Class类
Constructor[] getDeclaredConstructors() 获取所有构造方法 包括私有
Constructor getDeclaredConstructor(Class...parmType) 获取指定的构造方法 可以获取私有构造3.取消反射时访问权限检查
AccessibleObject
void setAccessible(boolean flag) flag值为true 则取消权限检查常用子类
Constructor Method Field4.运行构造方法
反射获取方法并运行
1.获取字节码文件对象
2.获取指定的方法
Class类的方法
Method[] getMethods() 获取所有的公共权限的方法 包括继承
Method[] getDeclaredMethods() 获取所有的方法 包括私有 但是不包括继承
Method getMethod(String methodName,Class...paramType);
根据方法名 和参数数据类型 获取到指定的方法
Method getDeclaredMethod(String methodName,Class...paramType)
3.运行方法Method类
Object invoke(Object obj,Object...args) 运行方法
参数
Object obj:运行方法需要有对象支持 ,要运行哪个对象的方法 可以通过快捷方式创建
Object...args:运行方法需要的实际参数
返回值Object
方法运行可能会有返回值 如果有返回值 用Object类型接收
如果没有返回值 返回null值
根据当前类名获取配置文件
文件要放在src目录下
类名.class.getClassLoader().getResourceAsStream("config03.properties");