在创建 ClassName[]数组时,并不会创建对应对象,也不会初始化对应类,会创建一个编译时类型 [+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.Object
String[]‘s class is class [Ljava.lang.String;
int[]‘s class is class [I
char[]‘s class is class [C
byte[]‘s class is class [B
boolean[]‘s class is class [Z
特别的 这些数组的父类为Object,二维数组则多加一个[符号。
关于类初始化的复制顺序 如下代码的输出结果应该很好判断
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 = 1
Singleton.value2 = 0
会发现value2在自增后又被初始化为零了,而value1没有,static域的对象初始化的顺序是依照源文件声明的顺序初始化的,
在连接阶段的准备阶段会为静态域赋初值(int为0)
初始化阶段依照声明顺序,先初始化instance引用对象,调用Singleton构造函数 此前value1,value2的值在连接阶段被初始化为默认值0.
调用后各自增了1 然后再初始化value1,value2的值,因为value1未被赋初值,故不进行操作,value2的值为1。
==================================可不看=======================================================
public class MyTest03 {
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");
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
sub3
sub1
creating
类成员对象的初始化也依照定义顺序
==============================================================================================
接口中所有字段均为 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:
Father04
Child04
编译后就算把接口的字节码删除依然不会报错,static final的字段由于是编译时常量 被写入了MyTest04的常量池中。
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