一,什么是类加载器
类加载器器:负责将.class文件(存储的物理文件)加载到内存中
类加载时机:
1,创建类的实例(对象)
2,调用类的方法
3,访问类或者接口的类变量,或者为该类变量赋值
4,使用反射方式来强制创建某个类或接口对应的java.lang.class对象
5,初始化某个类的之类
6,直接使用java.exe命令来运行某个主类
用到就加载,不用不加载
二,类加载器的过程
1,加载:通过报名+类名,获取这个类,准备用流进行传输,将这个类加载到内存中,加载完毕创建一个class对象
2,验证:文件中的信息是否符合虚拟机规范,有没有安全隐患
准备:初始化静态变量
解析:本类中如果用到其他类,此时就需要找到对应的类
3,初始化:静态变量赋值以及初始化其他资源
三,类加载器的分类
启动类加载器(BootstrapClassLoader):虚拟机内置的类加载器
平台了加载器(PlatformCladdLoader):负责加载JDK中一些特殊的模块
系统类加载器(SystemClassLoader):负责加载用户类路径上所指定的类库
1,双亲委派模型
通过getSystemClassLoader()方法获取一个系统类加载器,再通过getParent()方法获取父类加载器
2,类加载器器常用的方法
方法名 | 说明 |
public static ClassLoader getSystemClassLoader(); | 获取系统了加载器 |
public InputStream getResourceAsStream(String name); | 加载某一个资源文件 |
public class ClassLoaderDemo01 {
public static void main(String[] args) {
//系统的类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//平台的类加载器
ClassLoader parent = systemClassLoader.getParent();
//启动器类加载器
ClassLoader parent1 = parent.getParent();
//打印输出
System.out.println("系统类加载器"+systemClassLoader);
System.out.println("平台类加载器"+parent);
System.out.println("启动类加载器"+parent1);
}
}
public class MethodDemo01 {
public static void main(String[] args) throws IOException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//利用加载器去加载一个指定文件
//参数:文件的路径
//返回值:字节流中的数据
InputStream is = systemClassLoader.getResourceAsStream("p.properties");
//创建properties集合
Properties pp = new Properties();
pp.load(is);
System.out.println(pp);
is.close();
}
}
四,反射的概述
java反射机制
是在运行状态中,对于任意一个类,都能够知道这个类多有属性和方法;
对于任意一个对象,都能够调用它的任意属性和方法
这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制
用反射创建对象
反射调用成员变量,可以
反射调用成员方法,可以
利用反射调用用它类中的属性和方法时,无视修饰符
反射不是死的,比较灵活
java发射机制:
利用反射可以无视修饰符获取类里面的所有的属性和方法
先获取配置文件中的信息,动态后去信息斌常见对象和调用方法
五,获取class对象
以前调用一个类中的方法
创建这个类的对象
用对象调用方法
反射去调用一个类中的方法
利用class对象来创建的
反射方式:创建对象
反射方式:调用方法
1,获取class类的对象
Class.forName("全类名");
类名.class;
对象.getClass();
public class ReflectDemo01 {
/*获取class对象的三种方式*/
public static void main(String[] args) throws ClassNotFoundException {
//1,class类中的方法forName("全类名")
//全类名= 包名加类名;
Class<?> aClass = Class.forName("com.cheng.reflect01.Student");
System.out.println(aClass);
//2,通过class属性来获取
Class<Student> studentClass = Student.class;
System.out.println(studentClass);
//3,利用对象的getclass方法来获取class对象
//getclass方法是定义在Object中的
Student stu = new Student();
Class<? extends Student> aClass1 = stu.getClass();
System.out.println(aClass1);
}
}
六,反射获取构造方法
class类中用于获取构造方法的方法
Constructor<?>[] getConstructors();返回所有公共构造方法对象的数组
Constructor<?>[] getDeclardeConstructors();返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>...paramenterTypes);返回单个公共构造方法对象
Constructor<T> getDeclardeConstructor(Class<?>...paramenterTypes);返回单个构造方法对象
public class ReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
// 获取构造方法对象
//获取class对象
Class<?> aClass = Class.forName("com.cheng.reflect02.Student");
//获取构造方法对象,获取到是所有公共的构造方法
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
// 获取一个有参数的构造方法
// Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
// System.out.println(declaredConstructor);
}
}
Constructor类中用于创建对象的方法
T newlnstance(Object...initargs):根据指定的构造方法创建对象
public class ReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 获取构造方法对象
//获取class对象
Class<?> aClass = Class.forName("com.cheng.reflect02.Student");
// method01(aClass);
Constructor<?> constructor = aClass.getConstructor();
Student o = (Student) constructor.newInstance();
System.out.println(o);
}
}
如果使用了私有化的构造方法,需要取消检查
public class ReflectDemo02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取一个私有的构造方法并创建对象
Class<?> aClass = Class.forName("com.cheng.reflect02.Student");
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
/*被private修饰的成员不能直接使用
* 如果被反射强行获取并使用需要取消检查*/
declaredConstructor.setAccessible(true);
Student o = (Student) declaredConstructor.newInstance("zhangsan", 23);
System.out.println(o);
}
}
小结
获取calss对象
三种方式----Class.forName(”全类名“)
获取里面的构造方法对象
getConstructor()
getDeclaredConstructor()
如果是public的,直接创建对象
newlnstance()
如果是非public的需要取消检查,然后再创建对象
setAccessible(boolean)暴力反射
七,反射获取成员变量
1,获取Field对象
Filed[] getFields();返回所有公共成员变量的数组
Filed[] getDeclaredFields();返回所有成员变量的数组
Filed[] getField(String name);返回单个公共的成员变量数组
Filed[] getDeclaredField(String name);返回单个成员变量数组
public class ReflectDemo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
/*Field[] getFields(); 返回所有公共成员变量对象的数组
* Field[] getDeclaredFields(); 返回所有成员变量对象的数组
* Field getField(String name); 返回单个公共成员变量对象
* Field getDeclaredFields(); 返回单个成员变量对象*/
// method01();
// method02();
// method03();
// method04();
}
private static void method04() throws ClassNotFoundException, NoSuchFieldException {
// Field getDeclaredFields(); 返回单个成员变量对象
Class<?> aClass = Class.forName("com.cheng.reflect03.Student01");
Field name = aClass.getDeclaredField("money");
System.out.println(name);
}
private static void method03() throws ClassNotFoundException, NoSuchFieldException {
// Field getField(String name); 返回单个公共成员变量对象
// 想要获取的成员变量必须是真实存在的,且必须是public修饰的
Class<?> aClass = Class.forName("com.cheng.reflect03.Student01");
Field name = aClass.getField("name");
System.out.println(name);
}
private static void method02() throws ClassNotFoundException {
//Field[] getDeclaredFields(); 返回所有成员变量对象的数组
//1,获取class对象
Class<?> aClass = Class.forName("com.cheng.reflect03.Student01");
//2,获取Field对象
Field[] declaredFields = aClass.getDeclaredFields();
//输出
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
private static void method01() throws ClassNotFoundException {
// Field[] getFields(); 返回所有公共成员变量对象的数组
//1,获取class对象
Class aClass = Class.forName("com.cheng.reflect03.Student01");
//2,获取Field对象
Field[] fields = aClass.getFields();
//
for (Field field : fields) {
System.out.println(field);
}
}
}
2,赋值或者获取值
void set(Object obj,Object value);赋值
Object get(Object obj);获取值
public class ReflectDemo02 {
//给成员变量赋值或者获取值
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
// void set (Object obj ,Object value);给obj对象的成员赋值value
//Object get(Object obj); 返回由该Filed表示的字段在指定对象上的值
// method01();
//1,获取Class对象
Class<?> aClass = Class.forName("com.cheng.reflect03.Student01");
//2,获取成员变量Field对象
Field money = aClass.getDeclaredField("money");
//3,取消一下访问检查
money.setAccessible(true);
//4,调用get方法获取值
//4.1创建一个对象
Student01 student = (Student01) aClass.newInstance();
//4.2获取指定对象的成员变量的值
Object o = money.get(student);
//5,打印
System.out.println(o);
}
private static void method01() throws ClassNotFoundException, NoSuchFieldException, InstantiationException, IllegalAccessException {
// void set (Object obj ,Object value);给obj对象的成员赋值value
Class<?> aClass = Class.forName("com.cheng.reflect03.Student01");
Field name = aClass.getField("name");
//利用set方法进行赋值
//创建Student类的对象
Student01 student = (Student01) aClass.newInstance();
//有了对象才可以给指定的对象赋值
name.set(student, "zhangsan");
System.out.println(student);
}
}
八,反射获取成员方法
1,获取成员方法
Method[] getMethods();返回所有公共的成员方法,包括继承的
Method[] getDeclaredMethods();返回所有的成员方法,不包括继承的
Method getMethod(String name,Class<?>...paramenterTypes);返回单个公共的成员方法
Method getDeclaredMethod(String name,Class<?>...paramenterTypes);返回单个成员方法
//获取Method对象
public class ReflectDemo03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
/*Method[] getMethods();返回所有公共成员方法对象的数组,包括继承的
* Method[] getDeclaredMethods();返回所有成员方法对象的数组,不包括继承的
* Method getMethod(String name,Class<?>...parameterTypes);返回单个公共成员方法对象
* Method getDeclaredMethod(String name,Class<?>...parameterTypes);返回单个成员方法对象
* */
// method01();
// method02();
// method03();
Class<?> aClass = Class.forName("com.cheng.reflect03.Student02");
Method show = aClass.getDeclaredMethod("show");
System.out.println(show);
}
private static void method03() throws ClassNotFoundException, NoSuchMethodException {
Class<?> aClass = Class.forName("com.cheng.reflect03.Student02");
Method function01 = aClass.getMethod("function03",String.class);
System.out.println(function01);
}
private static void method02() throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.cheng.reflect03.Student02");
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
}
private static void method01() throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.cheng.reflect03.Student02");
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
2,运行方法
Object invoke(Object obj,Object...args );
//获取Method对象并运行
public class ReflectDemo04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
/*Object invoke(Object obj,Object...args);运行方法
* 参数一:用obj对象调用该方法
* 参数二:调用方法的传递参数(如果没有就不写)
* 返回值:方法的返回值(如果没有就不写)*/
//1,获取class对象
Class<?> aClass = Class.forName("com.cheng.reflect03.Student02");
//2,获取里面的method对象,function4
Method function04 = aClass.getMethod("function04", String.class);
//3,运行function4方法
//3.1创建一个Student02对象,当做方法的调用者
Student02 o = (Student02) aClass.newInstance();
//3.2运行方法
Object fun = function04.invoke(o, "张三");
//4,打印返回值
System.out.println(fun);
}
}