在使用控制面板时的实质:java
Hello.java
使用javac
,而后变成为Hello.class
经过运行java
这个命令,在类加载器中(含有加载,验证,准备,解析,初始化,使用,卸载),到jvm
为Java虚拟机中运行,在jvm
中有方法区,堆内存,线程栈,本地方法栈,PC
计数器。jvm
类加载器:测试
class
文件的版本是否能兼容当前的Java
虚拟机版本,而后class
文件要知足虚拟机的规范。final
修饰的类变量除外,final
变量就直接初始化为变量值,而类成员不同。xxx
,这种表明变为直接引用,什么是直接引用呢?就是内存地址,如咱们常见的xxx0203r0e
,这种。static
修饰的变量或者是static
静态代码块按照顺序组成构造器进行初始化变量。
JVM
spa
JVM:
方法区(保存全部类的信息,经过常量池来保存生成全部类信息的对象),堆内存,线程栈,本地方法栈,计数器。线程
// 在控制面板中,反编译 javap -c xxx 就是将字节码反编译为字节码的指令输出
public class Hello{ public Hello(); Code: 0: aload_0 1: invokespecial #1 4: return public static void main(java.lang.String[]); ... }
把程序放进jvm
中运行,到线程栈中运行,主方法main
(主线程),在线程栈中运行若是有遇到new
对象关键字时,main
这个主线程就会在本身的内存中(线程栈)声明一个的对象(对象的引用指向堆内存中开辟的对象),Hello hello
;在jvm
中有个堆内存,就会申请一片空间内存地址,即建立一个对象,实例变量,实例方法从方法区中指向堆内存。code
public class Hello{ public static void main(String[] args){ Hello hello = new Hello(); // 对象的声明 和 建立对象 } }
类加载到虚拟机中:对象
public class Demo static { System.out.println("静态代码块"); } { System.out.println("普通代码块"); } public Demo(){ System.out.println("构造方法"); } public static void main(String[] args){ new Demo(); } } // 结果 静态代码块 普通代码块 构造方法 // 加载 验证 准备 解析 初始化 使用 卸载 Demo.java -> Demo.class -> 加载进入虚拟机中,类加载器 (验证类信息,元素信息,版本,字节码,准备,初始化类变量,解析把符号引用解析为直接引用,进行初始化就是把static变量和static静态代码块进行初始化变量)
步骤:blog
在堆内存中执行的顺序就是加载实例信息,而后在进行构造方法。继承
了解static案例内存
// 父类 public class F static { System.out.println("F静态代码块"); } { System.out.println("F普通代码块"); } public F(){ System.out.println("F构造方法"); } } // 子类 public class S extends F static { System.out.println("S静态代码块"); } { System.out.println("S普通代码块"); } public S(){ super(); // 默认的 System.out.println("S构造方法"); } } // 测试 public class Demo public static void main(String[] args){ // 建立子类对象 new S(); } } // 结果 F静态代码块 S静态代码块 F普通代码块 F构造方法 S普通代码块 S构造方法
程序进入JVM
中的方法区,子类继承父类,父类进行加载实例信息进入到开辟的内存中,而后执行完再执行构造方法,在堆内存中new
一个对象,new S();
在子类的构造方法中会有默认的super()
,加载父类,若是子类调用默认调用super()
,而父类没有无参的构造方法,而是有参的构造方法,那么就要本身添加,在super(xxx)
中。