类加载器和反射

第十章——类加载器和反射

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 + '\'' +
                '}';
    }
}

posted @   snzjz  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示