目录
【类加载器】
【概述】:
负责将.class文件(字节码文件)(存储的物理文件)加载在到内存中
【类加载时机】
- 创建类的实例(对象)
- 调用类的类方法(静态方法)
- 访问类或者接口的类变量,或者为该类变量赋值(静态变量)
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
【类加载的过程】
- 加载
- 通过包名 + 类名,获取这个类,准备用流进行传输
- 在这个类加载到内存中
- 加载完毕创建一个class对象
- 验证
- 文件中的信息是否符合虚拟机规范
- 有没有安全隐患
- 准备
- 初始化静态变量
- 解析
-
本类中如果用到了其他类,此时就需要找到对应的类
- 初始化
- 静态变量赋值以及初始化其他资源
【类加载器分类】
- 启动类加载器(Bootstrap ClassLoader):虚拟机内置的类加载器。
- 平台类加载器(Platform Classloader):负责加载JDK中一些特殊的模块。
- 系统类加载器(System Classloader):负责加载用户类路径上所指定的类库。
【双亲委派模型】
例:
//系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//平台类加载器
ClassLoader classLoader = systemClassLoader.getParent();
//启动类加载器
ClassLoader classLoader1 = classLoader.getParent();
System.out.println("系统类加载器"+systemClassLoader);
System.out.println("平台类加载器"+classLoader);
System.out.println("启动类加载器"+classLoader1);
【成员方法】
public static ClassLoader getSystemClassLoader():获取系统类加载器
public InputStream getResourceAsStream(String name):加载某一个资源文件
例:
//加载资源文件
public static void main(String[] args) throws IOException {
//系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//利用加载器去加载一个指定的文件
//参数:文件的路径(相对路径:相对于src文件夹)
//返回值:字节流
InputStream is = systemClassLoader.getResourceAsStream("prop.properties");
Properties prop=new Properties();
prop.load(is);
System.out.println(prop);
is.close();
}
【反射】
【Java反射机制】
【概述】:
- 是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。
- 对于任意一个对象,都能够调用它的任意属性和方法。
- 这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
【注意】:
- 利用反射调用它类中的属性和方法时,无视修饰符
- 先获取配置文件中的信息,动态获取信息并创建对象和调用方法
【反射获取Class类对象】
- Class.forName(“全类名”);(全类名:包名+类名)
- 类名.class
- 对象.getClass();
例:
Class clazz = Class.forName("com.itheima.reflect1.Student");
System.out.println(clazz);
Class clazz1 = Student.class;
System.out.println(clazz1);
Student s=new Student();
Class clazz2 = s.getClass();
System.out.println(clazz2);
【反射获取构造方法、创建对象方法并使用】
【获取构造方法对象】
Constructor<?>[ ] getConstructors():返回所有公共构造方法对象的数组
Constructor<?>[ ] getDeclaredConstructors():返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象
例:
Class clazz = Class.forName("com.itheima.reflect2.Student");
//返回所有公共构造方法对象的数组
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//返回所有构造方法对象的数组
Constructor[] declaredConstructor = clazz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructor) {
System.out.println(constructor);
}
//返回单个公共构造方法对象
Constructor constructor = clazz.getConstructor(String.class,int.class);
System.out.println(constructor);
//返回单个构造方法对象
Constructor declaredConstructor1 = clazz.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor1);
【创建对象的方法】
T newInstance(Object... initargs):根据指定的构造方法创建对象
setAccessible(boolean flag):设置为true,表示取消访问检查
例:
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz=Class.forName("com.itheima.reflect2.Student");
//构造方法对象
Constructor constructor = clazz.getConstructor(String.class, int.class);
//利用newInstance 创建Student的对象
Student student=(Student) constructor.newInstance("zhangsan",23);
System.out.println(student);
//构造方法对象
Constructor constructor1 = clazz.getConstructor();
//利用空参来创建
Student student1 = (Student) constructor1.newInstance();
System.out.println(student1);
//获取一个私有化的构造方法
Constructor constructor2 = clazz.getDeclaredConstructor(String.class);
//被private修饰的成员,不能直接使用的
//如果用反射强行获取并使用,需要临时取消访问检查
constructor2.setAccessible(true);
Student student2=(Student) constructor2.newInstance("zhangsan");
System.out.println(student2);
}
【反射获取成员变量并使用】
【获取成员变量】
Field[ ] getFields():返回所有公共成员变量对象的数组
Field[ ] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象
例:
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class clazz=Class.forName("com.itheima.reflect3.Student");
//返回所有公共成员变量对象的数组
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
//返回所有成员变量对象的数组
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//返回单个公共成员变量对象
Field field = clazz.getField("name");
System.out.println(field);
//返回单个成员变量对象
Field field1 = clazz.getDeclaredField("money");
System.out.println(field1);
}
【对成员变量赋值或取获值】
void set(Object obj, Object value):给指定对象的成员变量赋值
Object get(Object obj): 返回指定对象的Field的值
例:
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz=Class.forName("com.itheima.reflect3.Student");
//给指定对象的成员变量赋值
Field field = clazz.getField("name");
Constructor constructor = clazz.getConstructor();
Student student = (Student) constructor.newInstance();
field.set(student,"zhangsan");
System.out.println(student);
//返回指定对象的Field的值
Field field1 = clazz.getDeclaredField("money");
field1.setAccessible(true);
Constructor constructor1 = clazz.getConstructor();
Student student1 = (Student) constructor1.newInstance();
Object o = field1.get(student1);
System.out.println(o);
}
【反射获取成员方法并运行】
【获取成员方法】
Method[ ] getMethods():返回所有公共成员方法对象的数组,包括继承的
Method[ ] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
例:
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class clazz=Class.forName("com.itheima.reflect4.Student");
//返回所有公共成员方法对象的数组,包括继承的
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method);
}
//返回所有成员方法对象的数组,不包括继承的
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//返回单个公共成员方法对象
Method method = clazz.getMethod("function1");
System.out.println(method);
Method method1 = clazz.getMethod("function2", String.class);
System.out.println(method1);
//返回单个成员方法对象
Method method2 = clazz.getDeclaredMethod("show");
System.out.println(method2);
}
【运行成员方法】
Object invoke(Object obj, Object... args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
例:
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz = Class.forName("com.itheima.reflect4.Student");
Method method = clazz.getMethod("function4", String.class);
Constructor constructor = clazz.getConstructor();
Student student = (Student) constructor.newInstance();
Object result = method.invoke(student, "zhangsan");
System.out.println(result);
}