04.26 day05 类加载器 类的加载流程 数据库连接池 设计模式

类的加载机制

跟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数据库
    开闭原则:对扩展开发 ,对修改关闭

猜你喜欢

转载自blog.csdn.net/Theniceday_99/article/details/89554707