类的加载机制
跟jvm虚拟机有关
什么是类的加载?
class称为字节码 编译命令 javac
解决内存中存的内容
1.java开发工具可以帮助我们将Java代码编译为class字节码
2.类加载器加载class字节码,将字节码里面的指令放到内存执行,并且将数据动态分配到jvm的内存模型中
3.jvm分区
类的加载流程
1、类的加载指的就是将class文件中的二进制数据读取到内存中,类、方法、常量、静态内容放在方法区
2、但是要在堆上面创建一个class对象,用来封装存储在方法区上面的数据结构
3、类加载最终的结果就是在堆产生了一个class对象,当前对象提供了访问方法区内容的接口。
类加载器主要加载的是class文件,加载class文件有哪些方式:
1、从本地的系统读取,直接加载
2、通过网络路径下载
3、Zip、jar包读取文档中的class文件
4、从某些数据库中获取class文件
5、将java源文件动态编译成class文件
类的生命周期
《深入理解java虚拟机》
《think in java》
加载:查找并加载类的二进制数据
1、通过类的全限定名来获取定义的二进制数据
2、将这个字节流所代表的静态储存内容放到方法区
3、java堆中生成一个代表当前对象的java。lang。Class对象,作为方法区的访问接口,整个类的生命周期中,最容易控制的阶段就是当前加载阶段,程序员最好控制这块,你可以自己定义类加载器来加载数据
验证:验证的目的主要是确保被加载的类的正确性
验证主要的内容是验证class文件中的信息是符合java虚拟机加载的要求,并且i的信息不能危害java虚拟机的安全
验证的内容:
1、文件格式的验证、;常量池中的数据是否有不被支持的类型
2、元数据的验证:保证类所描述的信息是符合java规范,当前这个类是否有父类,除了java。lang。Object之外
3、字节码校验:校验语法的正确性,是否符合逻辑
4、符号引用校验:确保解析的动作能正确运行
校验阶段是非常重要的阶段,但是又不是必须的。
准备:为类的静态变量分配内容,并且进行初始化为默认值。 为类变量(静态变量)分配内存、并且默认初始化
1、进行内存分配的时候仅包含static变量,不包含实例变量,实例变量对象创建的时候才分配内存。Static变量在方法区,实例变量----堆
2、这是所设置的初始值包括数据类型默认的值 int(0) String(null) Object(bull) 这个阶段数据默认值,并不会使用你自己定义的值 比如 public static int number = 10; 此时number为0,并不是10
解析:将类中符号转化为直接引用
虚拟机将常量池中的符号引用转化为直接引用。解析的动作主要包括:类、接口、字段、接口方法、方法类型
直接引用:直接指向目标对象的指针(地址),寻址
解析阶段顺序并不一定按照图中的顺序执行,有可能在初始化后才会执行这个动作。
初始化: 给类的静态变量进行赋值,jvm负责对类进行初始化,主要是对类的变量初始化。
1、声明类变量的时候指定初始化值
2、使用静态块来初始化值
jvm判断:
假如当前父类还没有初始化,先初始化父类
假如类中有初始化语句,依次执行初始化操作
成员变量初始化:new的时候、反射、初始化子类的时候父类也会初始化
类的销毁
类的销毁:
System.exit(0);
程序正常运行结束,java。lang。Class
程序遇到异常终止的情况。
对象的销毁:GC回收
===================================================
类加载器
一共分为三类(架构提供的):
1、启动类加载器(Bootstrap ClassLoader)主要负责加载存放在jdk/jre/lib文件夹下面的内容,并且能被jvm识别为类库。当前启动类加载器是无法直接被java程序引用。
2、扩展类加载器(Extension ClassLoader) 主要负责加载jdk/jre/lib/ext目录。(javax。*)
3、应用程序类加载器(Application ClassLoader)负责加载用户类路径下面的类,操作系统配置环境变量,在开发中写的java类,如果没有自定义类加载器,默认一般都使用他来加载应用程序
应用程序在运行的过程中,是由上面三种加载相互配置执行
注意:上图中的方向并不是继承关系,而是组合,相互之间可以调用
加载机制:
1、全盘负责:当一个类加载器负责加载某个class的时候,如果这个class所以依赖的其他class也由当前这个类加载器来完成。
2、父类委托:先让父加载器加载内容,只有父加载器无法加载的时候在尝试自己从类路径中加载
3、缓存机制:缓存机制主要是保证已经被加载过的类被缓存保存起来,当下次要在加载这个类的时候,直接从缓存区获取就行了。一旦修改了class,必须重启jvm才能生效。
类加载:
jvm启动的时候由jvm来加载
ClassLoader。loadClass();
Class。forName();
1、TestMain。class。getClassLoader------类加载器
Load。loadClass();
2、Class。forname(“com。project。bean。StudentBean”);也可以加载类
双亲委派模型
工作流程:
1.当ApplicationClassloader 加载一个class的时候,首先自己不会尝试加载这个类,而且将类加载委托给父类 extClassLoader
2、当extClassLoader加载一个class的时候,它首先不会尝试自己去加载,而且将当前类交给BootStrapClassload
3、此刻交给BootStrapClassload加载,但是如果加载失败,Jre/lib获取不到类信息,又会委托EXTBoostarp来加载
4、EXT加载失败,这个时候才会交给ApplicationClassloader加载,如果ApplicationClassloade也加载失败了,直接异常ClassNotFoundException
双亲委派模型意义:
防止内存中出现多份同样的字节码,
保证java程序运行稳定
一个Class加载一次
================================================
类的数据类型是class
下图是动态加载
Class.forName()和ClassLoader.loadClass()加载类有什么区别?
============================================
反射
反射的基本知识
1、类加载Class。forName(“类的全路径名称”)
类表现了面向对象中封装的特征,万物皆对象。
静态成员变量 ,普通的数据类型是否是对象?
int m = 10; 不是面向对象特征
普通的数据类型不是对象,但是java提供了包装类来表示基本数据类型,是一种对象。
Integer number = 10;
Integer number = new Integer();
静态成员变量可以看成类的属性,
类是谁的对象?
类是对象,类是java。lang。Class的对象
2、什么是动态加载?什么是静态加载?
java中类的加载或者对象的加载,一种是静态加载,一种是动态加载。
静态加载:在类编译的时候就已经在内存中加载了。new对象
动态加载:在类运行的时候才会去主动加载。反序列化、反射产生对象
优缺点:
静态加载:在编译的时候就加载,以后用的时候就不需要再编译了,但是消耗内存。
动态加载:在编译的时候不会加载对象,而是需要用某个功能在加载,不会浪费内存资源,效率更低。
在项目开发中两种方式都会用,一般来说框架的底层大量要有动态加载。
3、Class类的获取方式
java。lang。Class 存放在堆中,在程序中要获取当前对象提供了三种方式。
Object --------getClass() 所有对象都要当前方法
对象。class 静态属性 class静态属性任何一个对象都有
Class c = Class。forName(“类的全路径”)
总结:在运行期间,一个类只会产生一个Class对象,第一个方式获取类对象意义不大,必须得由对象反向才能获取,第二种方式需要导入当前对象,依赖性太强,第三种方式只需要知道类的名称(String)就可以获取类类型。
反射的操作
1、通过反射可以获取到构造方法并使用
通过Class对象获取到某个类中:构造方法、成员变量、成员方法
Class c = Class。forName(“类的全路径名称”)
c: 方法区访问数据的接口
访问私有的构造器
====================================
访问所有的公有属性
获取到某一个公有的属性
调用main方法
========================================
连接池
应用程序访问数据库,每次访问都要创建连接,用完了关闭连接。jdbc操作虽然简单,但是底层代码非常的复杂,操作Connection效率不高
为了提高效率,引入连接池
什么是连接池?
在程序之前的时候,预先在内存中开辟一块空间存放一定数量connction,当用户请求访问数据库的时候,直接从连接池中获取到连接就可以直接操作数据库,当本次操作完了,在将连接对象放回连接池
虽然占用点内存,但是提高了效率。
=================================================
设计模式 与 设计原则
-
工厂模式:专门用于生产对象
-
普通工厂
依赖倒转原则
在业务层要获取持久层对象 换成oracle数据库
开闭原则:对扩展开发 ,对修改关闭