Java基础-类加载机制与反射

news/2024/5/19 3:41:07 标签: Java, 反射, 类加载机制

类加载机制与反射">类加载机制反射

Java基础第四篇-类加载机制反射

1.类的加载、连接和初始化

JVM和类

一个Java程序启动一个Java虚拟机进程,当系统被终结时,JVM进程也会被终止。

有以下几种情况:

程序运行到最后正常结束

程序使用System.exit()结束程序

程序遇到未捕获的异常或者错误而结束

程序平台强制结束了JVM进程

类的加载

首先将类的class文件读入内存,创建一个java.lang.class对象。

类的连接

当类被加载之后,系统会生成一个对应的Class对象,接着把类的二进制数据合并到JRE中

类的初始化

虚拟机对类进行初始化,主要是静态Field进行初始化

2.类加载器

类加载器负责将.class文件加载到内存中,并生成java.lang.class对象。

类加载机制

全盘负责:当一个雷加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由此类加载器负责载入

父类委托:先让parent类加载器试图加载该Class

缓存机制:缓存机制会保证所有加载过的Class都会被缓存,当程序需要使用某个Class时,类加载器先从缓存区找,当缓存区不存在该Class对象,系统才会读取该类对应的二进制数据,转换成Class对象,存入缓存区。这也就是为什么修改了Class,不许重新启动JVM,程序新修改才会生效。

这个例子可以获取根类加载器的核心类库:

public class ClassLoaderPropTest {

    public static void main(String[] args) throws IOException {

        ClassLoader systemLoader = ClassLoader.getSystemClassLoader();

        System.out.println("系统类加载器:" + systemLoader);

        Enumeration<URL> eml = systemLoader.getResources("");

        while (eml.hasMoreElements())
        {
            System.out.println(eml.nextElement());
        }
        ClassLoader extensionLoader = systemLoader.getParent();

        System.out.println("拓展类加载器:" + extensionLoader);

        System.out.println("拓展类加载器的加载路径" + System.getProperty("java.ext.dirs"));

        System.out.println("拓展类加载器的Parent:" + extensionLoader.getParent());
    }
}

打印结果:

系统类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
file:/IdeaProject/out/production/IdeaProject/
拓展类加载器:sun.misc.Launcher$ExtClassLoader@60e53b93
拓展类加载器的加载路径/Users/blue/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
拓展类加载器的Parent:null

Extension Classloader被称为扩展类加载器,负责加载JRE的拓展目录中JAR包的类

从上面结果可以看出,系统类加载器的家在路径是当前程序运行路径,拓展类加载器的加载路径是jdk路径,但是拓展类加载器的父加载器是null,说明并不是根类加载器。

最后总结一下类加载器加载Class的步骤

  1. 检测Class是否再如果,如果有-> step 8
  2. 如果父类加载器不存在-> step 4,如果父类加载器存在-> step 3
  3. 请求使用父类加载器去载入Class,成功-> step 8,失败-> step 5
  4. 请求使用跟雷加载器载入Class,成功-> step 8,失败-> step 5
  5. 当前类加载器尝试寻找Class文件,找到-> step 6,失败-> step 7
  6. 从文件中载入Class,成功-> step 8
  7. 抛出ClassNotFound异常
  8. 返回java.lang.class对象

反射查看类信息">3.通过反射查看类信息

获得Class对象

由于每个类被加载后,系统都会生成一个对应的Class对象,通过该Class对象就可以访问到JVM中的这个类,获得Class对象的方式如下:

  • 使用Class类的forName(String clazzName)方法,参数是某个类的全限定类名
  • 使用某个类的class属性获取对应的Class对象,例如:Person.class
  • 使用某个对象的getClass(0方法

从Class中获取信息

大致包含了以下几个方法:

  • Constructor getConstructor(Class

反射生成并操作对象">4.利用反射生成并操作对象

创建对象

通过反射来生成对象有以下两种方式:

  • 使用Class对象的newInstance()方法
  • 先使用Class对象获取指定的Constructor对象,在调用Constructor对象的newInstance()方法。

举个例子:

private Object createObject(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

    Class<?> clazz = Class.forName(className);
    return clazz.newInstance();
}

调用方法

生成对象后,就可以通过getMethod()方法或者getMethods()方法来获取方法。

再通过invoke()方法来执行

访问属性值

通过getFields()或者getField()方法可以获取Class对象的Field。可以用以下两组方法来读取或者设置Field值

  • getXxx(Object obj):获取Field的属性值
  • setXxx(Object obj, Xxx val):将obj对象的Field设置成val值

http://www.niftyadmin.cn/n/1395332.html

相关文章

25个JQuery提示插件

http://www.iteye.com/news/21344转载于:https://www.cnblogs.com/jkyweb/archive/2011/08/04/2127780.html

为什么使用soap

http://www.ibm.com/developerworks/cn/xml/x-soap/part1/ http://yunan246.blog.163.com/blog/static/379555592008825112552659/

Android Room概述

说明&#xff1a; 大部分译自Android Developers的Room官网指导文档第一篇&#xff0c;小部分自己查阅资料和理解后加上。 原文地址&#xff1a;https://developer.android.com/training/data-storage/room/ 定义&#xff1a; Room 在SQLite上提供了一个抽象层&#xff0…

Android Room Entity使用

说明&#xff1a; Android Room 第二篇 - Entity使用 主要介绍entity的作用 原文地址&#xff1a;https://developer.android.com/training/data-storage/room/defining-data 第一篇&#xff1a;Android Room概述 使用Room entities 来定义数据 当你在使用Room的时候&…

Spread for Windows Forms快速入门(8)---单元格中用户动作触发的事件

这篇文章概括介绍了单元格的哪些事件是由控件的用户动作触发的。虽然它没有全面地列出的用户可能执行的每一个动作&#xff0c;但是它详细地描述了用户所使用的大部分普通操作所引发的事件。 因为某些动作一直出现&#xff0c;或者某些动作反复出现&#xff0c; 我们就在列表中…

Python3的print函数换行问题

前言 最近在看《python网络爬虫实战》&#xff0c;里面的第三章有个打印99乘法表的例子&#xff0c;但是由于书上代码基于Python2.X&#xff0c;我的电脑上是Python3.6&#xff0c;结果print()的时候出了问题&#xff0c;所以通过写博客的方式记录下来。 Ptyhon2.X 版本 pyt…

JavaScript js 兼容浏览器问题 兼容FireFox(FF)、IE的解决方法

网页开发经常要用到javascript&#xff0c;而每个浏览器对javascript 的支持有不同。这就需要我们去兼容他们&#xff0c;不然有些浏览器就无法运行我们的代码。就会造来客户的投诉&#xff0c;如果让BoSS知道了&#xff0c;这可不太好哦。下面是兼容IE 和FF的js脚本做法和分解…

Mac安装Scrapy及踩坑经验

前言 系统 - macOS 10.13.6 Python - 2.7 和 3.6 共存 Mac出厂自带python2.7版本&#xff0c;后面我又自己安装了Python3.X&#xff0c;于是电脑里就有两个版本共存的情况&#xff0c;今天打算装个Scrapy玩玩&#xff0c;不了解Scrapy的童鞋可以看官方文档&#xff1a;Scrapy…