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)的执行过程与之相似。