java 初始化器_Java中构造器的初始化

package object;

class Cup{

Cup(int marker){

System.out.println("Cup("+marker+")");

}

void f(int marker){

System.out.println("f("+marker+")");

}

}

class Cups {

static Cup cup1;

static Cup cup2;

static {

cup1 = new Cup(1);

cup2 = new Cup(2);

}

Cups(){

System.out.println("Cups()");

}

}

public class E08_StaticTest {

public static void main(String[] args) {

System.out.println("Inside main()");

//new Cups();

Cups.cup1.f(99);

}

static Cups cups1 = new Cups();

static Cups cups2 = new Cups();

} /* Output:

Cup(1)

Cup(2)

Cups()

Cups()

Inside main()

f(99)

*///:~

初始化的顺序为先静态对象,后非静态对象:在进入函数的入口地址(main)之前,首先初始化静态对象cups1和cups2两个静态对象,当初始化cups1时,进入Cups的构造器,里面又有两个静态对象cup1和cup2->Cup的构造器->输出Cup(1)、Cup(2)和Cups();当初始化cups2时,进入Cups的构造器,静态对象cup1和cup2已经创建,所以只输出Cups();然后进入main函数,顺序执行println函数和f()方法。

需要注意的是:此示例在main函数开始之前所有的类都被加载了,实际情况通常并非如此,此示例中所有的事物都通过static联系起来。

package object;

class Mug

{

Mug(int marker)

{

System.out.println("Mug(" + marker + ")");

}

void f(int marker)

{

System.out.println("f(" + marker + ")");

}

}

public class Test

{

Mug mug1;

Mug mug2;

{

mug1 = new Mug(1);

mug2 = new Mug(2);

System.out.println("mug1和mug2 初始化了");

}

Test()

{

System.out.println("Mugs()");

}

Test(int i)

{

System.out.println("Mugs(int)");

}

public static void main(String[] args)

{

System.out.println("Inside main()");

new Test();

System.out.println("new Mugs() completed");

new Test(1);

System.out.println("new Mugs(1) completed");

}

}/*Output

Inside main()

Mug(1)

Mug(2)

mug1和mug2 初始化了

Mugs()

new Mugs() completed

Mug(1)

Mug(2)

mug1和mug2 初始化了

Mugs(int)

new Mugs(1) completed

*///:~

这个例子中没有用到static关键字,则每次对匿名内部类进行初始化时相应的操作都会执行,而不是将带有static的对象只执行一次。

//: polymorphism/E15_PolyConstructors2.java

/****************** Exercise 15 *****************

* Add a RectangularGlyph to PolyConstructors.java

* and demonstrate the problem described in this

* section.

***********************************************/

package operators;

class Glyph{

void draw(){System.out.println("Glyph.draw()");}

Glyph(){

System.out.println("Glyph() before draw()");

draw();

System.out.println("Glyph() after draw()");

}

}

class RoundGlyph extends Glyph{

private int radius = 1;

RoundGlyph(int r){

radius = r;

System.out.println("RoundGlyph.RoundGlyph() , radius ="+radius);

}

void draw() {

System.out.println("RoundGlyph.draw() , radius ="+radius);

}

}

class RectangularGlyph extends Glyph {

private int width = 4;

private int height = 5;

RectangularGlyph(int width, int height) {

this.width = width;

this.height = height;

System.out.println("RectangularGlyph.RectangularGlyph(), width = " +

width + ", height = " + height);

}

void draw() {

System.out.println("RectangularGlyph.draw(), area = " + width *

height);

}

}

public class E03_Aliasing2 {

public static void main(String[] args) {

new RoundGlyph(5);

new RectangularGlyph(2,2);

}

} /* Output:

Glyph() before draw()

RoundGlyph.draw(), radius = 0

Glyph() after draw()

RoundGlyph.RoundGlyph(), radius = 5

Glyph() before draw()

RectangularGlyph.draw(), area = 0

Glyph() after draw()

RectangularGlyph.RectangularGlyph(), width = 2, height = 2

*///:~

上面这个例子在子代对象未完全构造之前调用了子代中的方法draw();结果就出现了隐藏错误。new RoundGlyph(5)->调用RoundGlyph构造器,发现有父代->调用Glyph构造器,顺序执行构造器内的语句,输出Glyph() before draw();执行到draw()时由于动态绑定执行RoundGlyph类中的draw()方法,输出RoundGlyph.draw(), radius = 0,此时radius并不等于默认的1(和想要的不一样),原因是还没执行到RoundGlyph构造器部分;再执行System.out.println("Glyph() after draw()");输出Glyph() after draw()->调用RoundGlyph构造器,将5传递给radius,输出RoundGlyph.RoundGlyph(), radius = 5。

new RectangularGlyph(2,2)的执行过程与之相似。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值