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

来源:互联网 发布:oracle数据迁移方式 编辑:程序博客网 时间:2024/05/01 03:48

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

    同样的,我们以LinkdeHashMap为例,解释内部类的定位和为什么成员内部类可以访问外部类的成员变量。
    上JDK源码(部分细节删除)
  1. public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{
  2. private abstract class LinkedHashIterator<T> implements Iterator<T> {
  3. Entry<K,V> nextEntry = header.after;
  4. Entry<K,V> lastReturned = null;
  5. int expectedModCount = modCount;
  6. public boolean hasNext() {
  7. return nextEntry != header;
  8. }
  9. public void remove() {
  10. }
  11. Entry<K,V> nextEntry() {
  12. }
  13. }
  14. private class KeyIterator extends LinkedHashIterator<K> {
  15. public K next() { return nextEntry().getKey(); }
  16. }
  17. private class ValueIterator extends LinkedHashIterator<V> {
  18. public V next() { return nextEntry().value; }
  19. }
  20. private class EntryIterator extends LinkedHashIterator<Map.Entry<K,V>> {
  21. public Map.Entry<K,V> next() { return nextEntry(); }
  22. }
  23. }
    上面的LinkdeHashMap定义了一个抽象内部类和几个抽象内部类的实现类作为成员内部类。这么做的好处是什么呢,很容易看到:这样做成员内部类可以以很爽的直接使用外部类的方法和成员变量(modCount / header...)。就像我们把心脏作为内部类作为内部类定义在人体类的内部,这样一方面保护了心脏的功能不被当做普通的抽水泵使用(可见性控制),同时我们可以直接使用人体中的血液、能量等,而不需要人体再传输给心脏了(减少沟通成本)。

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

2. 实现原理

    其实现方式是,在内部类中持有一个外部类类型的变量;下面是外部类和内部类的定义,下图是反编译内部类后的输出(没有截图常量池)
  1. public class InnerClassFinalVar {
  2. String ss ="g g s";
  3. class InstanceInnerClass{
  4. private int v = 0;
  5. private void print(){
  6. System.out.println("InstanceInnerClass : "+ss);
  7. }
  8. }
  9. }
 
可以看到第一行,在内部类的内部维护了一个名称为this&0, 类型为我定义的外部类,的变量,同时这个变量被finnal修饰;同时,在下图黄字部分deputfield,是编译器将外部类的的变量赋值给this&0,这样就在内部类持有了一个外部类类型的变量,用来方位外部类的成员。

 
阅读全文
0 0