Java 类加载器、反射

1. 类加载器

我们程序猿编写的是java文件,编译之后就是class文件,但并不是编译完成之后就能用了,具体的使用,得加载到虚拟机中运行,那么从硬盘到虚拟机内存中的这个步骤,就会使用到这边的类加载器!

1.1 类加载时机

一句话概括就是你用到的时候,他才会把class文件放入内存。那具体是什么时机呢?

  1. 你new 一个对象的时候
  2. 调用静态方法或者调用静态变量,也就是当你用类名直接点方法,或者点具体的变量的时候。
  3. 反射,强制创建一个对象。
  4. 创建子类的时候,父类也会被创建
  5. 通过java.exe 运行某个类的时候

1.2 类加载过程

1.3 类加载器种类

了解一下就好分别是启动类加载器、平台类加载器、系统类加载器、除此之外我们这也可以自定义加载器,而我们用的最多的其实就是这个系统类加载器。这些加载器能加载的范围不一样。

代码看一下,比较特殊的就是启动类是null,null就是他的地址。这边还有个方法就是通过类加载器去加载文件,注意这个文件是在src目录下的。

 public static void main(String[] args) throws IOException {
        //系统类加载器
        ClassLoader classloader1 =  ClassLoader.getSystemClassLoader();
        //平台类加载器
        ClassLoader parent = classloader1.getParent();
        //启动类加载器
        ClassLoader parent1 = parent.getParent();

        System.out.println(classloader1);
        System.out.println(parent);
        System.out.println(parent1);

        InputStream resourceAsStream = classloader1.getResourceAsStream("test.properties");
        Properties pp = new Properties();
        pp.load(resourceAsStream);
        System.out.println(pp);

        resourceAsStream.close();
    }

2. 反射

 我直接形容一下使用到反射的场景,我们一般创建对象都是通过new ,但试想一种场景,我编写好了100个类,我现在还没想好运行哪一个类的哪一个方法,怎么办?我编写代码的时候我也不知道我会用到具体哪个类,具体哪个方法。那么这个时候就需要用到动态配置,到时候运行的时候我改一下配置文件,我想运行哪个类就运行哪个类,想用哪个方法用哪个方法岂不美哉?反射就可以实现。下面代码见。

2.1 获取class 对象(3种方式)

public static void main(String[] args) throws ClassNotFoundException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");
        //第二种方式
        Class<Yasuo> aClass1 = Yasuo.class;
        //第三种方式
        Yasuo yasuo = new Yasuo();
        Class<? extends Yasuo> aClass2 = yasuo.getClass();
       //这边注意一下 aClass==aClass1==aClass2 这三个都是相等的

    }

2.2 获取类的属性

一个class有三大属性,field 是成员变量,construct是构造方法,method 是成员方法。

2.2.1 获取构造方法

 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");

        //获取所有公有的构造方法 public 修饰的
        Constructor<?>[] constructors = aClass.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("getConstructors"+constructor);
        }

        //获取所有构造方法
        Constructor<?>[] constructorsAll = aClass.getDeclaredConstructors();
        for (Constructor constructor : constructorsAll) {
            System.out.println("getDeclaredConstructors"+constructor);
        }

        //根据入参返回具体构造方法,这边的入参数是class,获取的只能公有的私有的获取不到
        //返回的是public Yasuo()
        Constructor<?> constructor = aClass.getConstructor();
        System.out.println("获取无参构造" + constructor);

        //private Yasuo(int age) 获取私有的只能是这个方法,当然也可以获取公有的
        Constructor<?> constructor2 = aClass.getDeclaredConstructor(int.class);
        System.out.println("获取无参构造1" + constructor2);

        
    }

2.2.2 反射创建对象

 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");
        //反射创建对象,这边等于new,当然无参构造也是一样的道理
        Constructor<?> constructor = aClass.getConstructor(int.class, String.class);
        Yasuo hasaki = (Yasuo) constructor.newInstance(23, "hasaki");
        System.out.println(hasaki);
        //这边构造有新的方法,了解一下就行
        Yasuo o1 = (Yasuo) aClass.newInstance();
        //获取私有构造方法,需要强制访问,暴力反射!!!!
        Constructor<?> constructor1 = aClass.getDeclaredConstructor(int.class);
        //强制访问私有方法
        constructor1.setAccessible(true);
        Yasuo o = (Yasuo) constructor1.newInstance(122);
    }

2.2.3 获取所有成员变量

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");
        //反射获取成员变量,public
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println("获取所有公共的成员方法"+field);
        }
        //获取所有
        Field[] fieldsAll = aClass.getDeclaredFields();
        for (Field field : fieldsAll) {
            System.out.println("所有"+field);
        }
        //获取单个公有的,同理获取私有的就不演示了
        Field nickname = aClass.getField("nickname");
        System.out.println("单个"+nickname);
    }

2.2.4 get&set

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");
        Yasuo o = (Yasuo) aClass.newInstance();
        Field msg = aClass.getDeclaredField("r");
        msg.set(o,"hasaihasaihasai");
        System.out.println(o);
        //有的小伙伴就要问了直接
        //o.setAge();多方便,但是这个方法是可以在没有set方法的时候给变量赋值
        Field nickname = aClass.getDeclaredField("nickname");
        String o1 = (String) nickname.get(o);
        System.out.println(o1);
    }

 2.2.5 获取成员方法

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");
        //获取所有方法,这个会返回父类的所有方法,不包括私有方法
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println("所有方法"+method);
        }
        //获取自己的成员方法,包含自己的私有方法
        Method[] methodsSelf = aClass.getDeclaredMethods();
        for (Method method : methodsSelf) {
            System.out.println("自己的方法"+method);
        }
        //获取单个方法
        Method getAge = aClass.getMethod("getAge");
        System.out.println("单个"+getAge);
        //获取有参数的方法
        Method setAge = aClass.getMethod("setAge", int.class);
        System.out.println("单个setAge"+setAge);
        //获取私有的方法
        Method kill = aClass.getDeclaredMethod("kill");
        System.out.println("kill"+kill);
    }

2.2.6 使用方法 invoke

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //第一种方式
        Class<?> aClass = Class.forName("com.yxlm.dmxy.Yasuo");
        Method kill = aClass.getDeclaredMethod("kill");
        Constructor<?> constructor = aClass.getConstructor(int.class, String.class);
        kill.setAccessible(true);
        kill.invoke(constructor.newInstance(1,"haihaihai!!!"));
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值