[java][反射]类的加载与反射机制(一)

1 篇文章 0 订阅

一 类的加载、连接、和初始化

1 JVM和类

    当调用java命令运行某个程序时,就会自动开启一个进程。无论程序多么复杂,该程序启动了多少线程,他们都在这个JVM的进程里,只有当出现下面四种情况,进程才会停止:

  •     程序运行到最后,正常结束
  •     遇到了System.exit()或Runtime.getRuntime().exit()代码结束程序
  •     遇到了未捕获的异常或错误的结束程序
  •     当JVM所在平台强制结束程序

2 类的加载

当程序主动使用某个类时,若该类还未被加载到内存中,则JVM或通过加载、连接、初始化三个阶段进行该类的初始化。类的加载就是将该类读入内存,并创建一个java.lang.Class的对象。类的来源主要有以下四种

  •     本地系统中的
  •     jar包中的
  •     网络上的
  •     把一个java源文件动态编译,并执行加载

3 类的连接

当类被加载之后,会产生一个对应的Class对象,接着将会进入连接阶段,链接阶段主要是将类的二进制数据合并到JRE中。连接阶段由可分为验证、准备、解析三个阶段

  •     验证:检查被加载的是否有正确的结构
  •     准备:为该类的类变量分配内存,并设置默认初始值
  •     解析:将类的二进制数据中的符号引用替换成直接引用

4 类的初始化

对类变量初始化主要有两种方式:1)声明变量时初始化,2)静态语句块中初始化


5 类的初始化时机

java程序首次通过下面6种方式来使用某个类或接口时,就会初始化该类或接口

  • 创建某个类的对象时,创建对象有三种方式1)通过new关键字2)通过反射来创建对象3)通过反序列化创建对象
  • 调用某个类的静态方法
  • 访问某个类的静态变量时,或为某个静态变量赋值时
  • 通过反射来创建某个类的class文件对象时(forName方法)
  • 初始化某个类的子类时
  • 直接食用java.exe命令来运行某个主类时(在终端使用输入java命令来运行一个类)

值得注意的是:一个被final修饰的类变量,如果能在编译阶段就确定了值,这个静态变量就会变成宏变量,也就是说编译器会将程序所有使用该变量的地方都换成该变量的值,所以即使访问了这个静态变量也不会初始化该类


6 类加载器ClassLoader

类加载器是将类的class文件(本地磁盘或者网络上的)加载到内存中并生成Class对象。当JVM启动时会由三种类加载器组成初始化类加载器的层次结构。

  • Bootstrap ClassLoader:根类加载器,负责加载java核心类($JAVA_HOME中jre/lib/rt.jar里所有的class),由C++实现不属于ClassLoader
  • Extension ClassLoader:扩展类加载器,负责加载JRE扩展目录中的JAR包的类($JAVA_HOME中jre/lib/ext.jar里所有的class
  • Application ClassLoader:系统类加载器,加载classpath中指定的jar包及目录中class

7 类加载机制

双亲委派机制工作原理

双亲委派模式要求除了顶层的启动类加载器外,其余的类加载器都应当有自己的父类加载器,请注意双亲委派模式中的父子关系并非通常所说的类继承关系,而是采用组合关系来复用父类加载器的相关代码,类加载器间的关系如下:

8 获取class对象的三种方法

  • 通过Class类的forName(String clazzName)该方法是通过传入一个类的全限定类名(完整包名+类名)来获取class对象
  • 通过某个类的class属性来获取该类的class对象,例如:Person.class
  • 调用某个对象的getClass()方法,例如new Person().getClass

第一种方法和第二种方法都是通过类来得到该类的class对象,相比之下第二种方式比第一种方式有以下两种好处

  1. 更安全,第二种方法在编译时期就可以检查该类的对象是否存在
  2. 效率更高,因为不需要调用方法所以效率高

但是如果想要通过类的名字创建该类的class对象,只能通过第一种方法,系统会根据名字来查找是否存在这个类的class文件如果不存在则会抛出ClassNotFoundException

9 获取Class的信息

可以通过getConstructor()、getDeclaredConstructor()、getMethod()、getDeclaredMethod()等方法获取类的构造方法、普通方法、成员变量、内部类等信息,详情参看API文档


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值