您的位置:首页 > 编程语言 > Java开发

Java-内部类(三)成员内部类就应该访问外部类的成员!!

2017-08-04 17:46 267 查看


1. 成员内部类就应该访问外部类的成员!

    同样的,我们以LinkdeHashMap为例,解释内部类的定位和为什么成员内部类可以访问外部类的成员变量。
    上JDK源码(部分细节删除)

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{



private abstract class LinkedHashIterator<T> implements Iterator<T> {

Entry<K,V> nextEntry= header.after;

Entry<K,V> lastReturned = null;

int expectedModCount = modCount;


public boolean hasNext() {

return nextEntry != header;

}


public void remove() {

}


Entry<K,V> nextEntry() {


}

}


private class KeyIterator extends LinkedHashIterator<K> {

public K next() { return nextEntry().getKey(); }

}


private class ValueIterator extends LinkedHashIterator<V> {

public V next() { return nextEntry().value; }

}


private class EntryIterator extends LinkedHashIterator<Map.Entry<K,V>> {

public Map.Entry<K,V> next() { return nextEntry(); }

}

}


    上面的LinkdeHashMap定义了一个抽象内部类和几个抽象内部类的实现类作为成员内部类。这么做的好处是什么呢,很容易看到:这样做成员内部类可以以很爽的直接使用外部类的方法和成员变量(modCount / header...)。就像我们把心脏作为内部类作为内部类定义在人体类的内部,这样一方面保护了心脏的功能不被当做普通的抽水泵使用(可见性控制),同时我们可以直接使用人体中的血液、能量等,而不需要人体再传输给心脏了(减少沟通成本)。

    以上,就是说成员内部类的定位之一就是要方便的同外部类沟通。

2. 实现原理

    其实现方式是,在内部类中持有一个外部类类型的变量;下面是外部类和内部类的定义,下图是反编译内部类后的输出(没有截图常量池)

public class InnerClassFinalVar {


String ss ="g g s";


class InstanceInnerClass{

private int v = 0;

private void print(){

System.out.println("InstanceInnerClass : "+ss);

}

}

}


 


可以看到第一行,在内部类的内部维护了一个名称为this&0, 类型为我定义的外部类,的变量,同时这个变量被finnal修饰;同时,在下图黄字部分deputfield,是编译器将外部类的的变量赋值给this&0,这样就在内部类持有了一个外部类类型的变量,用来方位外部类的成员。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐