类加载器
当程序要使用某个类时,如果该类还未被加载到内存中,则系统通过加载,连接,初始化三步来实现对这个类进行初始化。
加载
就是指将class文件读入内存 ,并为之创建一个Class对象。
任何类被使用时系统都会建立一个class对象
连接:
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化 就是我们以前讲过的初始化步骤
类初始化时机
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
类加载器
类加载器
负责将class文件加载到内存中,并为之生成对应的class对象
虽然我们不要关心类加载机制,但是了解这个机制我们就能更好地理解程序的运行
类加载器的组成
Bootstrap ClassLoader 根类加载器
引导类加载器,负责java核心类的加载,例:System,String 在jar lib 目录下 rt.jar 文件中
Extension ClassLoader 扩展加载器
负责jar的扩展目录中jar包的加载。
在jdk中jre lib ext 目录
System ClassLoader 系统类加载器
负责在jvm启动是加载来自java命令的class文件,以及classpath环境所指定的jar包和类路径
反射
java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任何一个对象,都能调用他的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
要想解刨一个类,必须先要获取该类的字节码文件对象,而解刨使用的就是Class类中的方法,所以先要获取到每个字节码文件对应的Class类型的对象
动态代理
XJad 反编译工具
native 本地意思
反射高级应用
动态代理
代理:
本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
举例: 春季回家买票让人代买
动态代理:
在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理就是通过反射生成的一个代理
在java 中java.lang.reflect 包下提供了一个Proxy类 和一个invooationHardler接口 ,通过使用这个类和接口就可以生成代理对象,jdk提供的代理只能针对接口做代理。我们有更强大的cglib
Proxy 类中的方法创建动态代理对象
public static Object newProxyinstance(classLoader loader,Class<?>[] interfaces,InvocationHandler h)
最终会调用invocationHandler 的方法
InvocationHandler
Object invoke (Object proxy.Method method.Objce[] aree);
动态代理:就是使用一个特定对象,帮我们完成公共的事情
模板设计模式
概述:
模板方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中实现
优点:
使用模板方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
缺点:
如果算法骨架要修改的话,则需要修改抽象类
装饰设计模式
概述:
装饰模式就是使用该类的一个子类的实例,在客户端将这个子类实例交给装饰类,是继承的替代方案
优点:
使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能
缺点:
正因为可以随意组合,所以可能出现一些不合理的逻辑
JDK 5 新特性
自动装箱和拆箱
泛型
增强for循环
静态带入
可变参数
枚举
枚举概述
是指将变量的值一一列举出来,变量的值只限于列举串来的值的范围内,举例:一周只有7天,一年只有12个月等
回想单例设计模式:单例类是一个类只有一个实例
那么多列类就是一个类有多个实例,单不是无限个数的实例,而是有限个数的实例,这才是枚举类。
enum 修改类
枚举项,枚举项,枚举项;
高级应用
可以在把变量名当做当前的构造实例使用 也可以重写当前类的方法
枚举项(){
}
注意事项:
enum
enum 类的子类
枚举项放在第一行
后面没有东西分好可以省略
可以有构造器 但必须是private 默认private 构造; 枚举的特殊用法 枚举(“”)
枚举类可以有抽象方法,但是枚举项必须重写该方法
枚举在switch 中结合使用
枚举中的常用方法
int compareTo(E o); //进行索引比较
String name(); 当前枚举项
int ordinal(); 索引
String toString(); //当前toString() 方法
<T> T valueOf(Class<T> type,String name); //获取到到当前实例对象
values() 遍历
此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,他遍历枚举类的所有枚举值非常方便
![](/qrcode.jpg)
jdk 7 特性
二进制字面量
jdk7 可以使用二进制来表示整数(byte,short,int 和long) .使用二进制字面量的好处是,可以使代码更容易被理解。语法非常简单,只要在二进制数值前面加OB 或者OB
int x = Ob100101;
数字字面量可以出现下划线
int y = 1_1123_1000;
//不能出现在进制标识和数值之间
int z = 0x111_2222;
switch语句可以使用字符串
泛型简化
ArrayList<String> array = new ArrayList<>();
异常的多个catch合并
try-with-resources 语句
public method(){
//try (必须是java.lang.AutoCloseable的子类对象){。。。}
try(当前需要关闭的异常类){
}catch(){
}
}
jdk 8 特性
允许接口中有默认方法
定义default 方法
定义static 方法
lambda 表达式
一般都是3个版本为一个节点,jdk5/8都是用的最普遍的,而且官方也宣布jdk11将会是后面几年持续更新修复的版本。