博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类的加载连接初始化顺序 (二)
阅读量:7222 次
发布时间:2019-06-29

本文共 4324 字,大约阅读时间需要 14 分钟。

1.数组对象的使用,不会导致对应类的初始化。

在创建 ClassName[]数组时,并不会创建对应对象,也不会初始化对应类,会创建一个编译时类型(其数组类型是JVM在运行时期动态生成的,不是由类加载器加载的,即没有对应的ClassLoader。调用getClassLoader会返回对用元素的ClassLoader) [+L+类全名 如下:

public class MyTest02 {	public static void main(String[] args) {		Sub[] subs = new Sub[1];		Sub[][] subss = new Sub[1][1];		String[] strs = new String[1];		int[] is = new int[1];		char[] chars = new char[1];		byte[] bs = new byte[1];		boolean[] bo = new boolean[1];		System.out.println("Sub[]'s class is       "+subs.getClass());		System.out.println("Sub[][]'s class is     "+subss.getClass());		System.out.println("Sub[]'s father's class "+subs.getClass().getSuperclass());		System.out.println("String[]'s class is    "+strs.getClass());		System.out.println("int[]'s class is       "+is.getClass());		System.out.println("char[]'s class is      "+chars.getClass());		System.out.println("byte[]'s class is      "+bs.getClass());		System.out.println("boolean[]'s class is   "+bo.getClass());	}}class Sub{	static {		System.out.println("Sub static block");	}}//~out:Sub[]'s class is       class [Ljvm.Sub;Sub[][]'s class is     class [[Ljvm.Sub;Sub[]'s father's class class java.lang.ObjectString[]'s class is    class [Ljava.lang.String;int[]'s class is       class [Ichar[]'s class is      class [Cbyte[]'s class is      class [Bboolean[]'s class is   class [Z

 特别的 这些数组的父类为Object,二维数组则多加一个[符号。

 

2.初始化中各字段初始化的先后顺序

关于类初始化的复制顺序 如下代码的输出结果应该很好判断

public class MyTest03 {	public static void main(String[] args) {		;		System.out.println("Singleton.value1 = "+Singleton.getInstance().value1);		System.out.println("Singleton.value2 = "+Singleton.getInstance().value2);	}	}class Singleton{	public static int value1;	public static int value2 = 0;	private static Singleton instance = new Singleton();	Singleton(){		value1++;		value2++;	}	public static Singleton getInstance() {		return instance;	}	}//~out:

Singleton.value1 = 1

Singleton.value2 = 1

 但我们调整一下static域字段的定义顺序:

public class MyTest03 {	public static void main(String[] args) {		System.out.println("Singleton.value1 = "+Singleton.getInstance().value1);		System.out.println("Singleton.value2 = "+Singleton.getInstance().value2);	}	}class Singleton{	private static Singleton instance = new Singleton();         public static int value1;	public static int value2 = 0;	Singleton(){		value1++;		value2++;	}	public static Singleton getInstance() {		return instance;	}	}//~out:Singleton.value1 = 1Singleton.value2 = 0

会发现value2在自增后又被初始化为零了,而value1没有,static域的对象初始化的顺序是依照源文件声明的顺序初始化的,

连接阶段准备阶段会为静态域赋初值(int为0)

初始化阶段依照声明顺序,先初始化instance引用对象,调用Singleton构造函数 此前value1,value2的值在连接阶段被初始化为默认值0.

调用后各自增了1 然后再初始化value1,value2的值,因为value1未被赋初值,故不进行操作,value2的值为1。

==================================可不看=======================================================public class MyTest0 public static void main(String[] args) {

  Singleton.getInstance(); }

}class Singleton{		private static Singleton instance = new Singleton();	public Sub sub1;	public Sub sub2 = new Sub("sub2");        {
  sub1 = new Sub("123");      } public Sub sub3 = new Sub("sub3"); Singleton(){ sub1 = new Sub("sub1"); System.out.println("creating"); } public static Singleton getInstance() { return instance; } }class Sub{ Sub(String str){ System.out.println(str); }}//~out: sub2 123sub3 sub1creating

 类成员对象的初始化也依照定义顺序

==============================================================================================

3.接口的初始化

接口中所有字段均为 public static final

public class MyTest04 {	MyTest04(String str){		System.out.println(str);	}	public static void main(String[] args) {		System.out.println(Father04.str);		System.out.println(Child04.str);	}}interface Father04{	String str = "Father04";}interface Child04 extends Father04{	String str = "Child04";}//~out:Father04Child04

编译后就算把接口的字节码删除依然不会报错,

static final的字段由于是编译时常量 被写入了MyTest04的常量池中,所以不会首次主动使用Father04。

JVM规范允许类加载器在预料到某个类将要被使用时就预先加载它,如果在预先加载时遇到了.class文件缺失或者存在错误,类加载器必须在程序首次主动使用时才报告错误(LinkageError错误)

public class MyTest04 {	public static void main(String[] args) {		Child04.sub.toString();	}}interface Father04{	String str = "Father04";	Sub sub = new Sub("father");}interface Child04 extends Father04{	String str = "Child04";	Sub sub = new Sub("child");}class Sub{	Sub(String str){		System.out.println(str);	}}//~out:child

初始化子接口时,并不会初始化其父接口

转载于:https://www.cnblogs.com/chafanbusi/p/10641184.html

你可能感兴趣的文章
FastSocket
查看>>
ionic $ionicSlideBoxDelegate 滑动框事件
查看>>
点击文字,把input type="radio"也选中
查看>>
第一章 Java多线程技能
查看>>
Java 集合系列-第八篇-Map架构
查看>>
springmvc 3.2 @MatrixVariable bug 2
查看>>
React-Native PanResponder手势识别器
查看>>
IOS11 光标错位问题
查看>>
如何设计用户登录
查看>>
linux安装mysql5.7.19
查看>>
Zookeeper+ActiveMQ 集群实现
查看>>
加权有向图问题2----多源最短路径问题(Floyd算法)和关键路径算法
查看>>
logback logback.xml常用配置详解(三) <filter>
查看>>
KgMall B2B/B2B2c/C2C版店铺商号初始化
查看>>
Linux内核的ioctl函数学习
查看>>
Liunx Shell入门
查看>>
Thread的中断
查看>>
linux --- 内存管理
查看>>
PostgreSQL
查看>>
CPU 超线程、多核
查看>>