Android記憶體流失的情境 (1)

來源:互聯網
上載者:User

標籤:inner   結果   代碼   outer   stat   new   參數   main   私人屬性   

情境一:匿名內部類、非靜態內部類隱式持有外部類的引用非靜態內部類樣本
 1 public class Test { 2     private int testValue = 1; 3  4     public class Outer { 5         private int outerValue = 2; 6  7         public class Inner { 8             private int innerValue = 3; 9 10             public void print() {11                 System.out.println("testValue=" + testValue + ", outerValue=" + outerValue12                         + ", innerValue=" + innerValue);13             }14         }15     }16 17     public static void main(String[] args) {18         Test test = new Test();19         Outer outer = test.new Outer();20         Outer.Inner inner = outer.new Inner();21         inner.print();22     }23 }

如19-20行所示,在外部類外執行個體化非靜態內部類時,需要通過外部類的執行個體.new進行構造。

使用 javac Test.java進行編譯,產生Test$Outer$Inner.class、Test$Outer.class、Test.class幾個class檔案。使用javap -p class_file_name查看,結果如下:

? ~/Programming/java  javap -p "Test.class"Compiled from "Test.java"public class Test {    private int testValue;    public Test();    public static void main(java.lang.String[]);    static int access$000(Test);}? ~/Programming/java  javap -p "Test\$Outer.class"Compiled from "Test.java"public class Test$Outer {    private int outerValue;    final Test this$0;    public Test$Outer(Test);    static int access$100(Test$Outer);}? ~/Programming/java  javap -p "Test\$Outer\$Inner.class"Compiled from "Test.java"public class Test$Outer$Inner {    private int innerValue;    final Test$Outer this$1;    public Test$Outer$Inner(Test$Outer);    public void print();}

 從產生的class檔案可以看出,內部類的建構函式被自動加上以外部類對象為參數,並且內部類有一個成員指向一個外部類對象(Test$Outer的this$0,Test$Outer$Inner的this$1)。

外部類和內部類之間可以相互訪問對方的私人屬性,而編譯之後每個類都是單獨的class檔案,因此編譯器會自動產生相應的包存取權限的靜態方法(只有在需要的時候才會產生),來支援這種私人屬性的訪問(Test中為testValue產生的access$000靜態方法,Test$Outer中為outerValue產生的access$100靜態方法)。

匿名內部類樣本
 1 public class AnonymousTest { 2     private int testValue = 1; 3  4     public interface IAnonymous { 5         void print(); 6     } 7  8     private final IAnonymous anonymous = new IAnonymous() { 9         private int innerValue = 2;10 11         public void print() {12             System.out.println("testValue=" + testValue + ", innerValue=" + innerValue);13         }14     };15 16     public static void main(String[] args) {17         AnonymousTest test = new AnonymousTest();18         test.anonymous.print();19     }20 }

使用 javac AnonymousTest.java進行編譯,產生AnonymousTest$1.class、AnonymousTest$IAnonymous.class、AnonymousTest.class幾個class檔案。使用javap -p class_file_name查看,結果如下:

? ~/Programming/java  javap -p AnonymousTest.classCompiled from "AnonymousTest.java"public class AnonymousTest {    private int testValue;    private final AnonymousTest$IAnonymous anonymous;    public AnonymousTest();    public static void main(java.lang.String[]);    static int access$000(AnonymousTest);}? ~/Programming/java  javap -p "AnonymousTest\$IAnonymous.class"Compiled from "AnonymousTest.java"public interface AnonymousTest$IAnonymous {    public abstract void print();}? ~/Programming/java  javap -p "AnonymousTest\$1.class"Compiled from "AnonymousTest.java"class AnonymousTest$1 implements AnonymousTest$IAnonymous {    private int innerValue;    final AnonymousTest this$0;    AnonymousTest$1(AnonymousTest);    public void print();}

從產生的class檔案可以看出,匿名內部類與非靜態內部類一樣,同樣持有外部類的引用。不同之處在於,匿名內部類的名字是外部類$數字。匿名內部類可以定義成員變數和成員函數,但是只能在本類中訪問,也無法通過JAVA代碼直接構造匿名內部類的新的執行個體。

結論

由於非靜態內部類和匿名內部類的執行個體會隱式持有外部類執行個體的引用,因此,若其生命週期比外部類執行個體長,會導致外部類執行個體無法回收而產生泄漏。因此,在使用要格外注意。

Android記憶體流失的情境 (1)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.