用户工具


用处1:维护某个对象的多个版本的状态

拿Iterator接口为例子。几乎所有容器类型(ArrayList,HashMap等)都实现了Iterator接口。但是并不是直接实现,而是通过内部类实现,通过内部类实现由什么好处呢?首先我们要知道迭代容器类对象时,迭代器只是维护了几个指针,当前访问到哪了,下个访问谁等等。

  • 如果由容器类(如ArrayList)直接实现Iterator接口。结果就是任意一个时刻只能有一个线程使用迭代器,如果多个线程同时访问,则指针就会错乱
  • 如果通过内部类实现,则可以支持多个线程同时访问(每个线程获取一个内部类的迭代器,相当于每个内部类的实例各自维护了一套迭代访问的指针)

下面是ArrayList类中关于迭代器的代码

    public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }

        public void remove() {
            if (lastRet < 0)
                throw new IllegalStateException();
            checkForComodification();

            try {
                ArrayList.this.remove(lastRet);
                cursor = lastRet;
                lastRet = -1;
                expectedModCount = modCount;
            } catch (IndexOutOfBoundsException ex) {
                throw new ConcurrentModificationException();
            }
        }
    }

用处2:多继承

企鹅既是鸟,也能跑

    public class Bird{ //some code here }
    public abstract class Runnable{ public abstract void run(); }
    public class Penguin extends Bird{
        public class Runner extends Runnable{
            //do something
        }
        public Runner penguinCanRun(){return new Runner();}
    }

用处3:对同一个接口有多种实现

public interface Runnable{ public void run(); }

public class Penguin{
    public void run(){  }
    public void swim(){ }

    public class Running implements Runnable{
        public void run(){Penguin.this.run();}
    }
    public class Swimming implements Runnable{
        public void run(){Penguin.this.swim();}
    }

    public Runner getRunner(){return new Running();}
    public Flyer getSwimmer(){return new Swimming();}
}