java类的主动使用/被动使用
对类的使用方式分为:主动使用、被动使用
所有的java虚拟机实现必须在每个类或接口被java程序“首次主动使用”时才初始化他们
ps:被动使用不会初始化类,但是有可能会加载类(JVM规范里没有说明)
并且,如果在加载的过程中,遇到了.class文件的缺失或者存在错误,类加载器只会在首次主动使用它们时才会报错,如果一直没有主动使用,则不会报错
主动使用:
创建类的实例、访问某个类或者接口的非final类型的静态变量/对该静态变量赋值、调用类的静态方法、反射、初始化一个类的子类、jvm启动时被标明为启动类的类(如Java Test、main方法所在的类)、jdk1.7开始提供动态语言的支持相关(很少使用)
ps:
初始化一个类的子类这条规则,不适用于接口,即:初始化一个类的子类,会先初始化它的父类,但是不一定会初始化它的接口。只有当首次使用该接口的静态变量时,才会初始化。
被动使用:
除了主动使用的其他使用方式
(1)通过子类引用父类的静态字段,为子类的被动使用,不会导致子类初始化
1 class Dfather{
2 static int count = 1;
3 static{
4 System.out.println("Initialize class Dfather");
5 }
6 }
7
8 class Dson extends Dfather{
9 static{
10 System.out.println("Initialize class Dson");
11 }
12 }
13
14 public class Test4 {
15 public static void main(String[] args) {
16 int x = Dson.count;
17 }
18 }
上面这个例子中,虽然是以Dson.count 形式调用的,但是因为count是Dfather的静态成员变量,所以只初始化Dfather类,而不初始化Dson类
(2)通过数组定义类引用类,为类的被动使用,不会触发此类的初始化
原因:其实数组已经不是E类型了,E的数组jvm在运行期,会动态生成一个新的类型,新类型为:
如果是一维数组,则为:[L+元素的类全名;二维数组,则为[[L+元素的类全名
如果是基础类型(int/float等),则为[I(int类型)、[F(float类型)等
1 class E{
2 static{
3 System.out.println("Initialize class E");
4 }
5 }
6
7 public class Test5 {
8 public static void main(String[] args) {
9 E[] e = new E[10];
10 }
11 }
(3)常量在编译阶段会存入调用方法所在的类的常量池中(这个例子存在F类的常量池中),本质上没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化
在本例子中,编译好了Test6后,类Test6和类F就完全没有关系了,甚至,你可以把类F的class文件删掉,也不影响程序的正常执行
1 class F{
2 static final int count = 1;
3 static{
4 System.out.println("Initialize class F");
5 }
6 }
7
8 public class Test6 {
9 public static void main(String[] args) {
10 int x = F.count;
11 }
12 }
如上例中,F类中定义的count是final对象,其在编译阶段就会存入调用类的常量池中
但是,如果把代码改成
1 class F{
2 static final String s = UUID.randomUUID().toString();
3 static{
4 System.out.println("Initialize class F");
5 }
6 }
7
8 public class Test6 {
9 public static void main(String[] args) {
10 String x = F.s;
11 }
12 }
则语句 "Initialize class F" 会打印出来,因为UUID.randomUUID().toString()这个方法,是运行期确认的,所以,这不是被动使用
java类的主动使用/被动使用的更多相关文章
- Java Web:主动和被动方式检测安全的框架
对于某些敏感的系统例如支付.交易需要为其加固,有必要将可能的攻击情况考虑进来加以防范,于是有了这么一个简易的安全框架.在前辈的代码上( 详见 :http://blog.csdn.net/zhongwe ...
- 深入剖析Classloader(一)--类的主动使用与被动使用
原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220115573911607 我们知道java运行的是这样的,首先java编译器将我们 ...
- 所有的Java虚拟机必须实现在每个类或接口被Java程序 “ 首次主动使用 ” 时才初始化他们
原文:https://www.cnblogs.com/fanjie/p/6916784.html Java程序对类的使用方式可分为两种– 主动使用– 被动使用 被动使用以后再讲,这里说说什么是主动使用 ...
- jvm系列(一):java类的加载机制
java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...
- 解析Java类和对象的初始化过程
类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...
- java类生命周期详细解析
(一)详解java类的生命周期 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前 ...
- Java类的生命周期详解
引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告 ...
- 【转】Java 类的生命周期详解
一. 引 言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大 ...
- JVM中java类的加载时机(转载:http://blog.csdn.net/chenleixing/article/details/47099725)
Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制.类从被加载到虚拟机内存中开始,到卸载出内 ...
随机推荐
- PyQt(Python+Qt)入门:Designer组件属性编辑界面中QWidget类相关属性详解
本文适用人员:本文比较长,适合不理解Qt Designer部件属性的人员阅读或资料查找. 声明: 1.如果有人认为本文是简单的复制粘贴+翻译而成,敬请读本文最后的后记: 2.本文为老猿Python学习 ...
- ASP.NET Log4net数据库日志新增记录客户端ip
LOG4数据库记录器XML配置 1 <appender name="ADONetAppender" type="log4net.Appender.ADONetApp ...
- bootstrap 扩展参数
后台接受的参数形式 前端加载bootstrap时做的处理
- 网络层-network layer(下):网络互连、子网掩码计算方法、Ipv4报头解析
第五章 网络层-Network Layer(下) 上一章讲了网络层的任务.提供的两种服务.五个重要的路由算法.以及网络层的拥塞控制和服务质量问题.这一部分主要讲一讲网络互连问题和Internet的网络 ...
- AcWing 406. 放置机器人
大型补档计划 题目链接 预处理每个列.行连续块. 每个每个列行只能在一个位置匹配,否则冲突. 符合二分图性质,跑匈牙利即可. 点数最坏情况 \(N * M\) (墙空地相间分布),边数最坏情况 \(N ...
- Java并发编程的艺术(五)——线程和线程的状态
线程 什么是线程 操作系统调度的最小单元就是线程,也叫轻量级进程. 为什么要使用多线程 多线程程序能够更有效率地利用多处理器核心. 用户响应时间更快. 方便程序员将程序模型映射到Java提供的多线程编 ...
- nginx学习之——信号控制和配置
一.信号控制 1)TERM, INT Quick shutdown \\麻溜停掉(暴力停止),一般不常用 // 启动和停止nginx 当前目录:/usr/local/bin/nginx 启动: ...
- Layui事件监听(表单和数据表格)
一.表单的事件监听 先介绍一下几个属性的用法 1.lay-filter 事件过滤器 相当于选择器,layui的专属选择器 2.lay-verify 验证属性 属性值可以是 :required必填项, ...
- Java8的Lambda表达式,你会不?
目录 理解Lambda 基础语法 函数式接口 常用的函数式接口 消费型接口 供给型接口 断言型接口 函数型接口 方法引用 数组引用 构造器引用 总结 参考阅读 理解Lambda Lambda表达式可以 ...
- Another MySQL daemon already running with the same unix socket. & ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (111)
mysql 断电后启动失败解决 应该是mysql.sock文件还存在. 把这个文件删掉就可以了. mv /var/lib/mysql/mysql.sock /var/lib/mysql/mysql.s ...