类的初始化
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
变量初始化的3种方法:
在构造器中设置值
在声明中设置值
初始化块
在一个类的声明中可以包含多个代码块,只要构造类的对象,这些块就会被执行。这种机制是不常见的。
举例:
class Person
{
String name;
static int age = 1;
{
age = age+1;
}
}
public class InitDemo1
{
public static void main(String args[]){
Person per1 = new Person();
Person per2 = new Person();
System.out.println(Person.age);
}
}
因为age是静态的,所有变量共享age,而每创建一个对象都会执行一次代码块,当per1被创建时,age值为2,当per2被创建时,age值为3.
举例:
class Person
{
String name;
static int age = 1;
public Person(){
System.out.println("****");
this.age = 2;
}
{
System.out.println("####");
age = age+1;
}
}
public class InitDemo1
{
public static void main(String args[]){
Person per1 = new Person();
Person per2 = new Person();
System.out.println(per2.age);
}
}
从结果可以看出,在初始化的时候,执行顺序为:先在声明中初始化,在执行初始化块,最后再执行构造函数!
静态代码块:代码块前面加static关键字,每当加载一个类的时候,需要执行静态代码块,以后创建对象的时候,不需要再执行静态代码块。
举例:
class Person
{
String name;
static int age = 1;
public Person(){
System.out.println("****");
this.age = 2;
}
{
System.out.println("####");
age = age+1;
}
static{
System.out.println("@@@@");
}
}
public class InitDemo1
{
public static void main(String args[]){
Person per1 = new Person();
Person per2 = new Person();
System.out.println(per2.age);
}
}
从结果可以已看出:
虽然创建2个对象,但静态代码块只被执行一次,而且是在创建对象之前执行
不管是代码块还是静态代码块,可以写在程序的任意位置,程序执行时,根据书写顺序执行,即如果有2个代码块,先执行写在前面的代码块,再执行写在后面的代码块(代码块和静态代码块要分开,静态代码块是在加载类的时候执行,只执行一次,代码块是在创建对象的时候执行,每创建一个执行一次)
Java类初始化深入分析 初始化(initialization)其实包含两部分:
1.类的初始化(initialization class & interface);
2.对象的创建(creation of new class instances)。
类的初始化其实是类加载(loading of classes),它是"对象的创建"的第一步。
顺序:类的加载肯定是第一步的,所以类的初始化在前,然后是对象的初始化。大体的初始化顺序是:类初始化 ->对象的初始化
举例:
class Bowl {
Bowl(int marker) {
System.out.println("Bowl(" + marker + ")");
}
void f1() {
System.out.println("Ok");
}
}
class Cupboard {
Bowl b1 = new Bowl(1);
static Bowl b2 = new Bowl(2);
{
System.out.println("
Cupboard()");
}
static Bowl b3 = new Bowl(3);
}
class Table {
Table() {
System.out.println("Table()");
}
Table(String a,int i){
this();
System.out.println("Ok");
}
}
public class Order {
static Cupboard t1 = new Cupboard();
static Table t2;
Bowl t3 = new Bowl(10);?
public static void main(String[] args) {
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
Order od = new Order();
od.t3.f1();
Table t4 = new Table("aa",1);
}
}
运行结果:
Bowl(2)
Bowl(3)
Bowl(1)//变量初始化完毕之后调用构造方法
Cupboard()
Creating new Cupboard() in main
Bowl(1)//第二次初始化非静态变量,静态变量初始化一次
Cupboard()
Creating new Cupboard() in main
Bowl(10)
Ok
Table()
Ok
分析:首先程序从public类开始,装载Order,class,运行static Cupboard t1 = new Cupboard();
由于t1是一个对象引用变量,首先得到初始化,然后转到Cupboard类的实例中,这时候程序开始初始化该实例中的变量,按照先static后非static变量初始化的顺序原则开始初始化各个变量,此时,
static Bowl b2 = new Bowl(2);
static Bowl b3 = new Bowl(3);
这两块先得到初始化然后?Bowl b1 = new Bowl(1);得到初始化(注意,这是非stataic变量)然后转到Cupboard() 构造函数。 此时Cupboard类已经初始化完毕,程序返回到public类中,又发现有 static Table t2; 开始初始化,由于t2只是个声明的变量,并没有创建一个Table对象让它指向,因此不要管这个t2变量。 在public类中,由于此时再没有static变量可以初始化,那么程序转到static方法main中进行,(注意:Bowl t3 = new Bowl(10); 这一句为什么得不到初始化,是因为此时没有创建类Order的实例,所以程序目前还不会初始化该代码,至于以后会不会初始化,还要看在main方法中是否会创建Order类的实例,如创建了,则一定初始化,否则不会。)
在main方法中,
System.out.println("Creating new Cupboard() in main");//首先打印该行要输出的语句 new Cupboard();?//创建了Cupboard类的实例,程序转到Cupboard中进行变量初始化,此时要注意:static变量的初始化,它只能初始化一次,也就是说,如果前面已经初始化过了,那么此时就不必要再初 始化了,这一点要牢记!!! System.out.println("Creating new Order() in main");//程序转入此行打印要输出的语句 Order od = new Order();//创建Order对象实例,程序转入实例od中,此时Bowl t3 = new Bowl(10); 这一句的t3会得到初始化,程序转到Bowl类中进行有关的操作,操作完后返回到main方法中 od.t3.f1();?//调用实例t3中的方法f()
Table t4 = new Table("aa",1); //创建Table类的实例,让t4指向这个实例,t4得到初始化,调用Table含 有参数的构造方
法,程序进行下去。
最后再总结一下:
初始化顺序是:
(1) 先是父类的static变量和static初始化块
(2)然后是子类的static变量和static初始化块?
(3)父类的实例变量、初始化快
(4)父类的构造方法
(5)子类的实例变量、初始化快
(6)子类构造方法