java初始化陷阱

import java.util.Iterator;
import java.util.NoSuchElementException;
public class InitOrder {

	public static void main(String[] args) {
		//错误的初始化
		new RoundGlyph(5);
		
		for (Iterator<Character> i = AbstractIterator.test("OPS"); i.hasNext();) {
            	System.out.print(i.next());
        }
		
		//正确的设计CorrectAbstractIterator
		System.out.println();
		for (Iterator<Character> i = CorrectAbstractIterator.test("OPS"); i.hasNext();) {
            	System.out.print(i.next());
        }
	}

}
abstract class Glyph {
	abstract void draw();
	Glyph() {
		System.out.println("Glyph() before draw()");
		draw();
		System.out.println("Glyph() after draw()");
	}
}
class RoundGlyph extends Glyph {
	int radius = 1;
	RoundGlyph(int r) {
		radius = r;
		System.out.println(
				"RoundGlyph.RoundGlyph(), radius = "
						+ radius);
	}
	void draw() {
		System.out.println(
				"RoundGlyph.draw(), radius = " + radius);
	}
}
abstract class AbstractIterator<T> implements Iterator<T> {

    	T next = nextElement();

    	public boolean hasNext() {
        	return next != null;
    	}

    	public T next() {
        	if (next == null) {
            		throw new NoSuchElementException();
        	}
        	T result = next;
        	next = nextElement();
        	return result;
    	}

    	public void remove() {
        	throw new UnsupportedOperationException();
    	}

    	protected abstract T nextElement();

    	public static Iterator<Character> test(final String s) {
       		return new AbstractIterator<Character>() {

            		private int cursor = 0;

            		protected Character nextElement() {
                		return cursor == s.length() ? null : s.charAt(cursor++);
            		}
        	};
    	}
}
//正确的设计
abstract class CorrectAbstractIterator<T> implements Iterator<T> {

    public abstract boolean hasNext();
	public T next() {
		if (!hasNext()) {
			throw new NoSuchElementException();
		}
		return nextElement();
	}
	public void remove() {
		throw new UnsupportedOperationException();
	}

	protected abstract T nextElement();

	public static Iterator<Character> test(final String s) {
		
		return new CorrectAbstractIterator<Character>() {

			private int cursor = 0;

			@Override protected Character nextElement() {
				return cursor == s.length() ? null : s.charAt(cursor++);
			}
			@Override public boolean hasNext() {
				return cursor < s.length();
			}
		};
	}
}

 输出为:

Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
OOPS

OPS

  * 初始化的实际过程是这样的:

   (1) 在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零。

   (2) 就象前面叙述的那样,调用基础类构建器。此时,被覆盖的draw()方法会得到调用, 此时会发现

        radius 的值为0,这是由于步骤(1)造成的。

   (3) 按照原先声明的顺序调用成员初始化代码。

   (4) 调用衍生类构建器的主体。

扫描二维码关注公众号,回复: 668408 查看本文章

  * 设计构建器时一个特别有效的规则是:用尽可能简单的方法使对象进入就绪状态;如果可能,避免调用

    任何方法。在构建器内唯一能够安全调用的是在基础类中具有final 属性的那些方法 (也适用于private方

    法,它们自动具有final 属性)。

 输出为:

Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
OOPS

OPS

  * 初始化的实际过程是这样的:

   (1) 在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零。

   (2) 就象前面叙述的那样,调用基础类构建器。此时,被覆盖的draw()方法会得到调用, 此时会发现

        radius 的值为0,这是由于步骤(1)造成的。

   (3) 按照原先声明的顺序调用成员初始化代码。

   (4) 调用衍生类构建器的主体。

  * 设计构建器时一个特别有效的规则是:用尽可能简单的方法使对象进入就绪状态;如果可能,避免调用

    任何方法。在构建器内唯一能够安全调用的是在基础类中具有final 属性的那些方法 (也适用于private方

    法,它们自动具有final 属性)。

猜你喜欢

转载自jaesonchen.iteye.com/blog/2286588