1:如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?‘
通过以下代码进行测试
public class InitializeBlockClass {
{field=200;}
public int field=100;
public InitializeBlockClass(int value) {
this.field=value;
}
public InitializeBlockClass() {
}
}
public class obj {
public static void main(String[] args) {
InitializeBlockClass obj=new InitializeBlockClass();
System.out.println(obj.field);
obj=new InitializeBlockClass(300);
System.out.println(obj.field);
}
}
测试结果为 100 300
Java字段初始化的规律:
静态初始化生成实例(new之后)变成你赋给他的值,先执行静态初始化,如果没有实例化,按照初始化和构造方法在程序中出现的顺序执行。
2:静态初始化块的执行顺序
执行下列代码
class Root
{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root()
{
System.out.println("Root的无参数的构造器");
}
}
class Mid extends Root
{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid()
{
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg)
{
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:" + msg);
}
}
class Leaf extends Mid
{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf()
{
//通过super调用父类中有一个字符串参数的构造器
super("Java初始化顺序演示");
System.out.println("执行Leaf的构造器");
}
{
public static void main(String[] args)
{
new Leaf();
}
代码的运行结果:
可以得出:首先执行的是父类静态初始化模块,然后是子类静态初始化模块,然后再是由父类到子类依次执行普通、无参、有参的构造器。
3:如何在静态方法中访问类的实例成员
public class Test2
{
int x=1;
static int y=2;
public static void method()//静态方法
{
System.out.println("实例变量x = " + new Test2().x);//在静态方法中访问类的实例变量需首先进行类的实例化
System.out.println("静态变量y = " + y);//在静态方法中可直接访问类的静态变量
}
{
Test2.method();
Test2 t = new Test2();
System.out.println("x = " + t.x);
}
}

4:使用类的静态字段和构造函数,可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向他查询“你已经创建了多少个对象?”。
代码如下:
private static int n = 0;
public Test2() {
n++;
}
public static int getNum() {
return n;
}
public static void main(String[] args) {
Test2 t1 = new Test2();
Test2 t2 = new Test2();
Test2 t3 = new Test2();
System.out.println("已生成对象个数为:" + Test2.getNum());
}
}
