Java笔记整理...

Java
一、类加载过程
Person person = new Person();
1)new的时候用到了Person.class文件,所以会先找.class文件,.class文件加载到内存
2)执行类中的static代码块,给Person.class初始化
3)在堆内存中开辟空间分配内存地址
4)在堆内存中建立对象的特有属性并进行默认初始化
5)对属性进行显式初始化
6)对构造代码块初始化
7)对对象进行与之对应的构造函数初始化
8)将内存地址付给栈中内存person变量

java Heap(堆):存储java实例或对象,是GC主要区域
java Stack(栈):java栈是和线程关联在一起,没创建一个线程,JVM就会为这个线程创建一个对应的java栈,在java栈中又会包含多个栈帧,每运行一个方法就创建一个线程,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧
PC Register(程序计数器):用于保存当前线程执行的内存地址,由于JVM程序是多线程执行的(线程轮流切换)所以为了保证线程切换回来后,还能恢复到原先状态就需要一个独立计数器,记录之前中断的地方,可见程序计数器是线程私有的
Native Method Stack(本地方法栈):和java栈类似,是为了JVM使用到的native方法服务的。
ClassLoader(类加载器):程序启动时并不会一次性加载程序所要用的所有.class文件,而是根据程序需要,通过Java的类加载机制ClassLoader来动态加载某个class文件到内存,从而只有class文件被载入到内存后,才能被其他class引用,所以ClassLoader就是用来动态加载class文件到内存中用的。

双亲机制:
原理:
ClassLoader使用的是双亲委托模型来搜索类的,每个ClassLoader实例都有一个弗雷加载器的引用,虚拟机内置的类加载器本身没有付类加载器,但可用作其他ClassLoader实例的父类加载器,当一个ClassLoader实例需要加载某个类是,它会试图亲自搜索某个方法之前,先把这个任务委托给付类加载器,这个过程是由下而上依次检查的,首先由最顶层的类加载器BootStrap ClassLoader试图加载,如果没有加载到,则把任务转交给Extension ClassLoader试图加载,如果也没有加载到,则转交给App ClassLoader进行加载,如果它也没有加载到的话,则返回给委托的发起者,由它指定的文件系统或网络等URL中加载该类,如果它们都没有加载到这个类,则抛出ClassNotFoundException,否则将这个未找到的类生成一个类的定义,并把它加载到内存中,最后返回这个类在内存中的class实例对象。

为什么使用双亲委托模型
因为这样可以避免重复加载,当父类已经加载了该类时,就没必要子类加载器再加载一次

JVM在搜索类时,如何判断两个class是相同的?
JVM在判定两个class是否相同时,不仅要判断两个类名是否相同,而且要判断是否由同一个类加载器实例加载的,只有两者同时满足,JVM才认为这两个class是相同的

Android类加载器
对于Android而言,最终的apk文件包含的是dex类型文件,dex文件是将class文件重新打包,打包规则不是简单地压缩,而是对class文件内部的个助攻函数表、变量进行优化,产生一个新的文件,即dex文件,因此加载这种特殊的class文件就需要特殊的类加载器DexClassLoader

Java中泛型

泛型是Java SE1.5新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法创建中,分别称为泛型类,泛型接口,泛型方法,Java语言引入泛型的好处是简单安全,没有泛型的情况下,是通过对类型Object的引用来实现参数“任意化”,“任意化'的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可预知的情况下进行的,对于强制类型转换错误,编译器可能不提示错误,在运行时抛异常,这是一个安全隐患。
泛型的好处是在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码重用率
1、泛型的类型参数只能是类类型(包含自定义类),不能是简单类型
2、同一泛型可对应多个版本,不同版本的泛型实例是不兼容的
3、反响的参数类型可以有多个
4、泛型的参数类型可以用extends语句,称”有界类型“
5、泛型的参数类型还可以是通配符类型 Clas< : > ClassType

你可能感兴趣的:(Java笔记整理...)