java类的初始化和实例化区别
结论:
参考https://blog.csdn.net/qq_43672627/article/details/86616624
类的初始化:是完成程序执行前的准备工作。在这个阶段,静态的(变量,方法,代码块)会被执行。同时在会开辟一块存储空间用来存放静态的数据。初始化只在类加载的时候执行一次。
类的实例化:是指创建一个对象的过程。这个过程中会在堆中开辟内存,将一些非静态的方法,变量存放在里面。在程序执行的过程中,可以创建多个对象,既多次实例化。每次实例化都会开辟一块新的内存。
1.主要区别
2.基础知识
2.1java类的生命周期:
指一个class文件从加载到卸载的全过程,类的完整生命周期包括7个部分:加载——验证——准备——解析——初始化——使用——卸载,如下图所示
其中,验证——准备——解析 称为连接阶段,除了解析外,其他阶段是顺序发生的,而解析可以与这些阶段交叉进行,因为Java支持动态绑定(晚期绑定),需要运行时才能确定具体类型;在使用阶段实例化对象
2.2类加载过程:
加载:通过类名获取类的二进制字节流是通过类加载器来完成的。其加载过程使用“双亲委派模型”
验证:当一个类被加载之后,必须要验证一下这个类是否合法,比如这个类是不是符合字节码的格式、变量与方法是不是有重复、数据类型是不是有效、继承与实现是否合乎标准等等。总之,这个阶段的目的就是保证加载的类是能够被jvm所运行。
准备:为类变量(静态变量)在方法区分配内存,并设置零值。注意:这里是类变量,不是实例变量,实例变量是对象分配到堆内存时根据运行时动态生成的。
解析:把常量池中的符号引用解析为直接引用:根据符号引用所作的描述,在内存中找到符合描述的目标并把目标指针指针返回。
初始化:类的初始化过程是这样的:按照顺序自上而下运行类中的变量赋值语句和静态语句,如果有父类,则首先按照顺序运行父类中的变量赋值语句和静态语句在类的初始化阶段,只会初始化与类相关的静态赋值语句和静态语句,也就是有static关键字修饰的信息,而没有static修饰的赋值语句和执行语句在实例化对象的时候才会运行。执行<clinit>()方法(clinit是class initialize的简写)
实例化:在堆区分配内存空间,执行实例对象初始化,设置引用变量a指向刚分配的内存地址
2.3 运行时区内存分配
3.具体流程
类A
public class A { private int m=2; private String str1="youyou"; public final static String MESS="world"; static String ms="world"; public String getName(String input){ String temp=input; return temp; } public static int getId(){return 0;} }
Test类
public class Test { public static void main(String[] args) { Class clazz=A.class; A a=new A(); A a1=new A(); } public void change(int i) { i=123; } }
以上面来举例
引用对象:A中成员B b,b即为引用对象,
常量三种:8种基本数据类型byte boolean,char short,float int,dobule long的具体的值,
受final修改的变量
“”双引号引起来的字符串
附:
java内存分配图解:https://blog.csdn.net/shunfa888/article/details/79765031
类成员变量和局部变量内存分配:https://www.cnblogs.com/chuanqi1995/p/11644334.html
类的加载过程详解:https://blog.csdn.net/yanliguoyifang/article/details/80964237