2013-05-07 2 views
2

Я знаю о внутреннем классе и вложенного класса от Java inner class and static nested classДоступ внешнего класса из внутреннего класса в Java

Но любой орган может сказать мне, что разница между Inner.redo1() и Inner.redo2() ?

Или Inner.print1() и Inner.print2() - то же самое?

public class Outer { 
    private String str = "outer"; 
    public void print() { 
     System.out.println("a"); 
    } 

    public class Inner { 
     public void redo1() { 
      print(); 
     } 
     public void redo2() { 
      Outer.this.print(); 
     } 
    } 
} 

PS: В java.util.ArrayList.Itr # удалить

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(); 
    } 
} 

Почему это использовать ArrayList.this.remove(lastRet); но не remove(lastRet);?

ответ

5

Но может ли любое тело сказать мне, в чем разница между Inner.redo1() и Inner.redo2()?

Inner.redo1() и Inner.redo2() действительно такие же. Нет семантической или функциональной разницы. redo2 более подробно. Вот и все.

Давайте сравним байткод каждого метода:

λ Desktop javap -c Outer.Inner 
Compiled from "Outer.java" 
public class Outer$Inner extends java.lang.Object{ 
final Outer this$0; 

public Outer$Inner(Outer); 
    Code: 
    0: aload_0 
    1: aload_1 
    2: putfield #1; //Field this$0:LOuter; 
    5: aload_0 
    6: invokespecial #2; //Method java/lang/Object."<init>":()V 
    9: return 

public void redo1(); 
    Code: 
    0: aload_0 
    1: getfield #1; //Field this$0:LOuter; 
    4: invokevirtual #3; //Method Outer.print:()V 
    7: return 

public void redo2(); 
    Code: 
    0: aload_0 
    1: getfield #1; //Field this$0:LOuter; 
    4: invokevirtual #3; //Method Outer.print:()V 
    7: return 

} 

То же байткод, такой же конечный результат, так же все.


Почему использовать ArrayList.this.remove (lastRet); но не удалять (lastRet); ?

Чтобы устранить, какой класс класса remove() фактически должен быть вызван. На самом деле это необходимо в этом случае! Без явного указания ArrayList.this.remove(lastRet), код не компилируется:

λ Desktop javac java/util/ArrayList.java 
java/util/ArrayList.java:810: remove() in java.util.ArrayList<E>.Itr cannot be applied to (int) 
       remove(lastRet); 
       ^
1 error 
1
  1. В вашем примере, они одинаковы. Но если есть существенная разница между внутренним экземпляром и внешним экземпляром, который повлияет на результат print(), тогда это будет другое.

  2. ArrayList.this.remove (lastRet) относится к экземпляру ArrayList (внешний класс), используя remove(). remove (lastRet) вместо этого сделает экземпляр любого внутреннего класса, чтобы использовать метод remove().

«Таким образом, правила для внутреннего класса ссылки себя или внешний экземпляр следующим образом:

■ Для ссылки на сам экземпляр внутреннего класса, внутри внутреннего кода класса, использование это

■ Чтобы ссылаться на «внешний это» (экземпляр внешнего класса) изнутри внутренний код класса."

-из SCJP 6 Кэти Сьерра и Берт Бейтс

Смежные вопросы