public class Test
{
public static void main(String[] args)
{
Super t = new Super();
}
}
class Super
{
static
{
System.out.println("静态加载执行输出");
int i;
System.out.println(i); //为什么这里没有I没有被初始化 我想问下这里JVM是怎样对内存操作的?把I压到内存的什么地方了 或者是可以做个标记不给I分配空间吗?类加在是放生在执行了JAVA 命令之后的吗??? }
}
{
public static void main(String[] args)
{
Super t = new Super();
}
}
class Super
{
static
{
System.out.println("静态加载执行输出");
int i;
System.out.println(i); //为什么这里没有I没有被初始化 我想问下这里JVM是怎样对内存操作的?把I压到内存的什么地方了 或者是可以做个标记不给I分配空间吗?类加在是放生在执行了JAVA 命令之后的吗??? }
}
以你的例子而言:
JVM虚拟机诞生->JVM加载Test类(Test的Class对象存储在堆区,Test字节码存储在方法区)->main方法压栈->加载Super类->初始化成员变量(int=0,boolean=false等,如果存在父类,先初始化父类)->执行静态块(你的i必须分配空间才能被使用)->调用Super构造方法(实例化Super对象)->main方法出栈->JVM虚拟机死亡
class Super
{
static
{
System.out.println("静态加载执行输出");
int i ;
// System.out.println(i); }
{ System.out.println("asdfasdffffffffffffffff");}
int i = test();
public Super() {
System.out.println("gouzhao");
}
public int test(){
System.out.println("test");
return 9;
}
}
java需要保证任何变量在使用之前得到正确的初始化,java按照它自己的方式达到了这样的要求,在函数中通过编译检查排除这样的错误。例如
void f() {
int i;
i++;
}
这样书写的代码在编译时就会报出i没有被初始化的错误;当然编译器是能够给i一个默认值的,但这很可能是一个程序书写的bug,如果给出了默认值,那等于就掩盖了这个错误。
如果是java类的primitive data 属性成员,情况就有点不同。因为任何方法都可以初始化或者使用这些数据,所以强迫去初始化它是不实际的。如果随便给它赋予一个废值也是不安全的,所以类的primitive data属性成员保证会获取一个初始值,比如int 类型的就是0,boolean类型的为false,char 是null。
Super t = new Super(); 执行时,引起类Super的加载和初始化,当执行静态块时
static
{
System.out.println("静态加载执行输出");
int i;
System.out.println(i);
} 在编译会报出错误,i没有初始化。这里相当于上面的f().