关于类加载机制的一些笔记

来源:互联网 发布:c语言生成随机数 编辑:程序博客网 时间:2024/05/21 12:45

类加载流程

基本过程:加载——验证——准备——解析——初始化——使用——卸载

加载时初始化顺序

先加载父类static变量,再加载子类static变量,再初始化父类普通成员变量和构造方法,再初始化子类成员变量和构造方法。

一个例子

class SingleTon {    private static SingleTon singleTon = new SingleTon();    public static int count1;    public static int count2 = 0;    private SingleTon() {        count1++;        count2++;    }    public static SingleTon getInstance() {        return singleTon;    }}public class Test {    public static void main(String[] args) {        SingleTon singleTon = SingleTon.getInstance();        System.out.println("count1=" + singleTon.count1);        System.out.println("count2=" + singleTon.count2)为 0  } }

输出结果为1和0

以下情况不会触发类的初始化

  • 调用父类静态变量
  • 调用final常量
  • 使用 A[] array = new A[10]

关于堆栈等变量的存储位置

  • 成员变量存在堆中(除了static和final),因为需要new出来才可以使用,依赖于对象实例
  • 局部变量(形参及其传来的值)的基本数据类型存在栈中(包括变量名及其值)
  • 对象的引用存在栈中,实例存在堆中
  • static一般存在方法区中
  • final存在常量池中,字符串没有new时存在常量池中,如果new String(“xxx”)则先寻找常量池,没有时在堆中存放,既而在常量池中再copy一份,也就是会存在两个对象实例
  • static final 应该也是常量池中,static 对象引用也是在栈中

关于内存泄漏部分问题

非静态内部类实例隐式持有外部对象的引用,注意内存泄漏问题
方法内部类(匿名内部类)访问方法的变量必须为final是为了保持对象生命周期比方法长时能够持有变量的值(copy值),之所以为final是因为要保持方法原来变量和copy后的值的一致性。

关于Kotlin优雅使用internal

可以使用@JvmName(‘funcn ame’)注解使用不规范方法名,java类将无法调用kotlin
可以直接粗暴使用

fun 'me  thod '(a:Int,b:Int):Int = a + b 

参考文章1
参考文章2