JVM-----在类的声明周期中,类的二进制数据位于方法区里,同时在堆区内还会有一个响应的描述这个类的Class对象.

Java虚拟机及程序的生命周期

当通过java命令运行一个程序时,就启动了一个java虚拟机进程.从开始到结束就是虚拟机的生命周期.以下情况下JVM将结束生命周期

1,程序正常执行结束

2,程序在执行过程中因为出现异常或者错误而终止

3,执行了System.exit()方法

4,由于操作系统出现错误而导致JVM进程终止

类的加载,连接和初始化

加载:查找并加载类的二进制数据.把类的class文件中的二进制数据读入到内存中,把它放在运行时数据区对方法区内.在堆上创建Class对象.用来封装在方法区内的数据结构.

加载方式:

1.本地加载

2.网络下载

3.zip jar中提取

4.从一个专有的数据库中提取

5.把一个java源文件动态编译为class文件

加载方式是由类加载器完成的,包括JVM自带的类加载器和用户继承ClassLoader类的实例.加载方式可以是首次使用主动加载或者预先加载.预先加载如果发现class文件不存在,只有在首次使用才会报告错误.LinkageError错误.

连接:把已经读到内存中的类的二进制数据合并到JVM运行时环境中去.

验证:确保被加载类的正确性.包括类文件的结构检查,语义检查,字节码验证,二进制兼容

准备:为类的静态变量分配内存,并将其初始化为默认值.

解析:把类中的符号引用转换为直接引用

初始化:给类的静态变量赋予正确的初始值 (首次主动使用才会进行这步骤).1,静态变量的声明进行初始化 2,静态代码块中进行初始化.

<1>假设这个类还没有被加载和连接,那就先进行加载和连接

<2>假如类存在直接的父类,并在这个父类还没有被初始化,那就先初始化直接的父类.

<3>假如类中存在初始化语句,那就依次执行这些初始化语句.

package init;

class Base{

static int a=1;

static{

System.out.println("init base");

}

}

class Sub extends Base{

static int b=1;

static{

System.out.println("init Sub");

}

}

public class InitTest {

static{

System.out.println("init initTest");

}

public static void main(String[] args) {

System.out.println("b="+Sub.b);//执行这行代码时,先依次初始化Base和Sub

}

}

如果把以上的main方法修改为以下:

public static void main(String[] args) {

Base base;//不会初始化Base类

System.out.println("After defining base");//执行这行代码时,先依次初始化Base和Sub

base=new Base();

System.out.println("After creating an object of Base");

System.out.println("a="+base.a);

System.out.println("b="+Sub.b);

}

执行结果变为:

init initTest

After defining base

init base

After creating an object of Base

a=1

init Sub

b=1

从以上总结出类的初始化时机:

对类或者接口的主动使用

1,创建类的示例,new 克隆 反射 反序列化

2,调用类的静态方法

3,访问某个类或者接口的静态变量,或者对该静态变量赋值

4,调用API中的某些反射方法.Class.forName()

5,初始化一个类的子类,

6,JVM启动时被标明为启动类的类.例如包含main()方法的类.

被动使用

1,对于final类型的静态变量,如果在编译时就能计算出变量的取值,那么这种变量就被看做是编译时常量,对这种常量的使用不会导致类的初始化.如果无法在编译期间进行值的确定那么就会转化为主动使用进行初始化操作.

class Base{

public final static int a=1;//编译时常量 不会导致初始化

static{

System.out.println("init base");

}

}

2.当JVM初始化一个类时,要求它的所有父类都已经被初始化,但是这条规则不适用于接口.

在初始化一个类时,并不会先初始化它所实现的接口

在初始化一个接口时,并不会先初始化它的父接口.

只有当首次使用特定接口的静态变量时,才会导致该接口的初始化.

只有当程序访问的静态变量或者静态方法的确在当前类或者接口中定义时,才可以看做是对类或者接口的主动使用.

package init;

class Base{

static int a=1;//编译时常量 不会导致初始化

static void method(){

System.out.println("method of Base");

}

static{

System.out.println("init base");

}

}

class Sub extends Base{

static{

System.out.println("init Sub");

}

}

public class InitTest {

static{

System.out.println("init initTest");

}

public static void main(String[] args) {

System.out.println("a="+Base.a);//仅仅初始化Base

Sub.method();

}

}

结果为:

init initTest

init base

a=1

method of Base

调用ClassLoader类的loadClass()方法加载一个类,并不是对类的主动使用,不会导致类的初始化操作.

package init;

class ClassA{

static{

System.out.println("now init classA");

}

}

public class ClassB {

public static void main(String[] args) throws Exception{

ClassLoader loader=ClassLoader.getSystemClassLoader();//获得系统类加载器

Class objClass=loader.loadClass("init.ClassA");//加载ClassA

System.out.println("after load ClassA");

System.out.println("before init ClassA");

objClass=Class.forName("init.ClassA");//初始化ClassA

}

}

执行结果:

after load ClassA before init ClassA now init classA

java声明时间为什么类型_JAVA--类的声明周期相关推荐

  1. java未知变量的类型_Java语言中类、变量及方法的声明 | 学步园

    类声明 [ public][ abstract][ final] class NameOfClass [ extends Super][ implements Interfaces] pubilc:声 ...

  2. java intf判断变量类型_Java 的数据类型

    数据类型 概要 Java是一种强类型语言,每个变量都必须声明其类型. Java的数据类型分为两大类:基本类型(primitive type)和引用类型 (reference type) Java中定义 ...

  3. java获取泛型的类型_Java反射获取泛型类型

    public class Person{ }importjava.lang.reflect.ParameterizedType;importjava.lang.reflect.Type;public ...

  4. date在java中是什么类型_java中date 是什么类型

    满意答案 1engwen 2016.08.20 采纳率:41%    等级:8 已帮助:1115人 java语言中的date类介绍及使用 在JDK1.0中,Date类是唯一的一个代表时间的类,但是由于 ...

  5. java怎么输入String类型_Java语言程序设计(五)从对话框获取输入及String类型

    1.String类型java char类型只能表示一个字符,为了表示一串字符,使用成为String(字符串)的数据类型,例以下述代码将消息声明为一个字符串.ide String message = & ...

  6. java 获取参数的类型_java反射获取方法名称,参数类型

    package com.mysec.reflex; import java.lang.reflect.Constructor; import java.lang.reflect.Field; impo ...

  7. java日期时间转日期_Java时间和日期指南

    java日期时间转日期 长期以来,正确处理日期,时间,时区,夏令时,and年等一直是我的烦恼. 本文并不是一个全面的指南时域,请参阅日期和时间在Java中 -更详细,但略有下降,ekhem,日期. 它 ...

  8. java中类成员的限定词_Java类中的限定词

    java语言中有四种不同的限定词,提供了四种不同的访问权限. 1) private 类中限定为private的成员,只能被这个类本身访问. 如果一个类的构造方法声明为private,则其它类不能生成该 ...

  9. java hh24miss_时间日期转换工具类,获取当前时间YYYYMMDD24HHMISS、YYYYMMDDHHMISS

    packagecom.ztesoft.iotcmp.util;importcom.ztesoft.zsmart.core.log.ZSmartLogger;importjava.sql.Timesta ...

最新文章

  1. linux raid md,具有不可预测功耗的情况下的Linux MD RAID弹性
  2. LeetCode35.搜索插入位置 JavaScript
  3. LeetCode刷题实战(2):Add Two Numbers
  4. c++ file* 句柄泄漏_C++核心指南:P.8 勿泄漏任务资源
  5. 系统设置参数说明11
  6. 异常处理简单例子--python except Exception as e
  7. MiniApp微信小程序入口在安卓手机桌面
  8. 2019蓝桥杯B组:完全二叉树权值
  9. html在线播放mp4文件,使用HTML5视频在Firefox中播放MP4文件
  10. FreeImage的学习总结总结(四)
  11. 学习笔记-网络安全(二)
  12. HikariCP源码分析
  13. 回溯算法求解桥本分数式
  14. 局域网下两台电脑ping不通的问题总结
  15. 国产高可用软件,双机热备与冷备的区别
  16. Ubuntu sudo apt-get 安装下载更新软件包命令详解
  17. 微信小程序实现可移动悬浮按钮(超简单)
  18. 论文翻译:LP-3DCNN: Unveiling Local Phase in 3D Convolutional Neural Networks
  19. 大数据采集技术与预处理
  20. 低智商和高智商的9个表现是什么

热门文章

  1. oracle大作业_最累人7大专业
  2. net空间一次购买终身使用_net域名与org域名哪个投资价值更高?
  3. Git push大文件失败的处理
  4. python读取文件夹下所有文件的名字_一键汇总同一文件夹下所有表格,三种小技巧分享给你...
  5. Django:ORM基本操作-CRUD,管理器对象objects,----->查询3(单条更新,批量更新)
  6. winform 读取用户控件的变量_winform中用户控件之间的传值
  7. nginx离线安装_做一个属于自己的离线下载服务器原来这么简单
  8. python语法报错_Python语法的常见错误和处理异常
  9. java输出 4 7什么意思_Java学习4_一些基础4_输入输出_16.5.7
  10. java junit mock_使用Mockito进行Java的Mock测试