第十章——类加载器和反射
1、类的加载
类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载
就是指将class文件读入内存,并为之创建一个Class对象。
任何类被使用时系统都会建立一个Class对象。
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化 就是我们以前讲过的初始化步骤
类初始化时机:
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
类加载器:
类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象。
虽然我们不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。
类加载器的组成
Bootstrap ClassLoader 根类加载器
Extension ClassLoader 扩展类加载器
Sysetm ClassLoader 系统类加载器
类加载器的作用:
Bootstrap ClassLoader 根类加载器
也被称为引导类加载器,负责Java核心类的加载
比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。
在JDK中JRE的lib目录下ext目录
Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
反射:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
获取构造方法
getConstructors
getDeclaredConstructors
创建对象
newInstance()
con.newInstance(“zhangsan", 20);
获取所有成员
getFields,getDeclaredFields
获取单个成员
getField,getDeclaredField
修改成员的值
set(Object obj,Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
获取所有方法
getMethods
getDeclaredMethods
获取单个方法
getMethod
getDeclaredMethod
暴力访问
method.setAccessible(true);
public class StudentDemo {
public static void main(String[] args) throws Exception{
//通过反射获取一个class文件对应Class对象
//方式1:在已经有对象的前提下获取
// Student student = new Student();
// Class<? extends Student> c1 = student.getClass();
// Class<? extends Student> c2 = student.getClass();
// System.out.println(c1==c2);
//方式2:可以直接通过类名的方式获取
// Class<Student> c1 = Student.class;
// Class<Student> c2 = Student.class;
// System.out.println(c1==c2);
//方式3:Class.forName()
Class<?> c1 = Class.forName("com.shujia.day20.Student");
// Class<?> c2 = Class.forName("com.shujia.day20.Student");
// System.out.println(c1==c2);
// 获取类中的构造方法并使用
// getConstructor() 只能获取某一个公共构造方法
// public Constructor<T> getConstructor(Class<?>... parameterTypes)
Constructor<?> cons1 = c1.getConstructor();
// System.out.println(cons1);
// Constructor<?> cons2 = c1.getConstructor(String.class,String.class);
// System.out.println(cons2);
Constructor<?> cons2 = c1.getDeclaredConstructor(String.class, String.class);
System.out.println(cons2);
Constructor<?> cons3 = c1.getDeclaredConstructor(String.class);
System.out.println(cons3);
//如何使用获取到的构造方法呢?
//public T newInstance(Object ... initargs)
Object o = cons1.newInstance();
System.out.println(o);
cons3.setAccessible(true);
Object o1 = cons3.newInstance("1001");
System.out.println(o1);
// 获取类中的成员变量并使用
//getField 只能获取公共的成员变量
Field like = c1.getField("like");
// Field id = c1.getField("id");
Field id = c1.getDeclaredField("id");
// 给对象o1中成员变量like进行赋值操作
like.set(o1, "骑自行车");
System.out.println(o1);
id.setAccessible(true);
id.set(o1,"1002");
System.out.println(o1);
// 获取类中的成员放啊并使用
Method fun1 = c1.getMethod("fun1");
System.out.println(fun1);
Method fun11 = c1.getMethod("fun1",String.class);
System.out.println(fun11);
// Method fun3 = c1.getMethod("fun3");
// System.out.println(fun3);
Method fun3 = c1.getDeclaredMethod("fun3");
System.out.println(fun3);
//使用成员方法
fun1.invoke(o1);
fun3.setAccessible(true);
fun3.invoke(o1);
}
}
============================================================
public class Student {
private String id;
String name;
protected int age;
public String like;
public Student() {
}
private Student(String id) {
this.id = id;
}
Student(String id, String name) {
this.id = id;
this.name = name;
}
protected Student(String id, String name, int age, String like) {
this.id = id;
this.name = name;
this.age = age;
this.like = like;
}
public void fun1(){
System.out.println("这是公共的无参成员方法");
}
public void fun1(String s){
System.out.println("这是有参数成员方法"+s);
}
private void fun3(){
System.out.println("这是私有的无参成员方法");
}
private void fun3(String s){
System.out.println("这是私有的有参数成员方法"+s);
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
", like='" + like + '\'' +
'}';
}
}
标签:反射,String,System,println,加载,id,out
From: https://www.cnblogs.com/snzjz/p/18475844