成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Java內部類的實現原理與可能的內存泄漏說明

瀏覽:90日期:2022-08-23 11:05:34

在使用java內部類的時候要注意可能引起的內存泄漏

代碼如下

package com.example;public class MyClass { public static void main(String[] args) throws Throwable { } public class A{ public void methed1(){ } } public static class B{ public void methed1(){ } }

編譯生成了如下文件

Java內部類的實現原理與可能的內存泄漏說明

反編譯MyClass

Java內部類的實現原理與可能的內存泄漏說明

反編譯MyClassA

Java內部類的實現原理與可能的內存泄漏說明

反編譯GlassB

Java內部類的實現原理與可能的內存泄漏說明

從反編譯的結果可以知道,內部類的實現其實是通過編譯器的語法糖實現的,通過生成相應的子類即以OutClassName$InteriorClassName命名的Class文件。

并添加構造函數,在構造函數中傳入外部類,這也是為什么內部類能使用外部類的方法與字段的原因。

我們明白了這個也就要小心,當外部類與內部類生命周期不一致的時候很有可能發生內存泄漏,例如在一個Activity啟動一個Thread執行一個任務,因為Thread是內部類持有了Activity的引用,當Activity銷毀的時候如果Thread的任務沒有執行完成,造成Activity的引用不能釋放,Activity不能被釋放而引起了內存泄漏。

這種情況下可以通過聲明一個static的內部類來解決問題,從反編譯中可以看出,聲明為static的類不會持有外部類的引用,如果你想使用外部類的話,可以通過軟引用的方式保存外部類的引用。

具體的代碼就不上了。

補充知識:Java內部類的底層實現原理

摘要:

定義:在一個類中創建另一個類,叫做成員內部類,這個內部類可以是靜態的,也可以是非靜態的。

已知靜態內部類的應用(可以解決的問題):

通過內部類解決java 的單繼承問題,外部類不能同時繼承的類可以交給內部類繼承

設計模式中,builder 模式通過定義一個靜態內部類實現

類型匯總:

靜態內部類

成員內部類

方法內部類

匿名內部類

一、靜態內部類

靜態內部類的定義和普通的靜態變量或者靜態方法的定義方法是一樣的,使用static關鍵字,只不過這次static是修飾在class上的,一般而言,只有靜態內部類才允許使用static關鍵字修飾,普通類的定義是不能用static關鍵字修飾的,這一點需要注意一下。下面定義一個靜態內部類:

public class Out { private static String name; private int age; public static class In{ private int age; public void sayHello(){ System.out.println('my name is : '+name); //--編譯報錯--- //System.out.println('my age is :'+ age); } }}

在上述代碼中,In這個類就是一個靜態內部類。我們說內部類是可以訪問外部類的私有字段和私有方法的,對于靜態內部類,它遵循一致的原則,只能訪問外部類的靜態成員。上述代碼中,外部類的非靜態私有字段age在靜態內部類中使不允許訪問的,而靜態字段name則是可訪問的。下面我們看,如何創建一個靜態內部類的實例對象。

public static void main(String [] args){ Out.In innerClass = new Out.In(); innerClass.sayHello();}

靜態內部類的實例對象創建還是比較簡潔的,不同于成員內部類,它不需要關聯外部類實例(具體的下文介紹),下面我們再看一段代碼:

public class Out { private static String name; public static class In{ public void sayHello(){ System.out.println(name); showName(); } } private static void showName(){ System.out.println(name); }}

上述代碼在內部類中兩次訪問了外部類的靜態成員,第一次訪問了靜態字段name,第二次訪問的靜態方法showName。在我們反編譯這個類之前,首先需要知道的是,所謂的內部類的概念只是出現在編譯階段,對于jvm層是沒有內部類這個概念的。也就是說,編譯器會將一個類編譯成一個源文件,對于內部類也是一樣,它會從它的外部類中抽離出來,增加一些與外部類的聯系,然后被編譯成一個單獨的源文件。下面我們先編譯運行之后,利用Dj反編譯class文件看看編譯器都做了些什么事情。

//這是我們的Out外部類public class Out{ //省去了一些不重要的部分 private static void showName() { System.out.println(name); } private static String name; static String access$000(){return name;} static void access$100(){showName();} }//這是我們的內部類public static class Out$In{ public void sayHello() { System.out.println(Out.access$000()); Out.access$100(); } public Out$In() { }}

相信大家也已經看出來這兩者之間的某種聯系,編譯器將Out這個類編譯成兩個獨立的class源文件。對于Out中所有的私有成員(也就是內部類分離出去之后不能訪問的成員),增設了可供調用的access$xxx方法,從而實現內部類與外部類之間的聯系。這就是他們的本質。

至于使用場景,一般來說,對于和外部類聯系緊密但是并不依賴于外部類實例的情況下,可以考慮定義成靜態內部類。下面我們看稍顯復雜的成員內部類。

二、成員內部類

我們說了,四種不同類型的內部類都各自有各自的使用場景,靜態內部類適合于那種和外部類關系密切但是并不依賴外部類實例的情況。但是對于需要和外部類實例相關聯的情況下,可以選擇將內部類定義成成員內部類。以下代碼定義了一個簡單的成員內部類:

public class Out { private String name; public void showName(){ System.out.println('my name is : '+name); } public class In{ public void sayHello(){ System.out.println(name); Out.this.showName(); } }}

以上定義了一個簡單的內部類In,我們的成員內部類可以直接訪問外部類的成員字段和成員方法,因為它是關聯著一個外部類實例的。下面我們看看在外部是如何創建該內部類實例的。

public static void main(String [] args){ Out out = new Out(); Out.In in = out.new In(); in.sayHello();}

因為成員內部類是關聯著一個具體的外部類實例的,所以它的實例創建必然是由外部類實例來創建的。對于實例的創建,我們只需要記住即可,成員內部類的實例創建需要關聯外部類實例對象,靜態內部類實例創建相對簡單。下面我們主要看看在編譯階段編譯器是如何保持內部類對外部類成員信息可訪問的。

//反編譯的Out外部類源碼public class Out{ //省略部分非核心代碼 public void showName() { System.out.println((new StringBuilder()).append('my name is : ').append(name).toString()); } private String name; static String access$000(Out o){return o.name;}}//反編譯的內部類In源碼public class Out$In{ public void sayHello() { System.out.println(Out.access$000(Out.this)); showName(); } final Out this$0; public Out$In() { this.this$0 = Out.this; super(); }}

由上述代碼其實我們可以知道,當我們利用外部類實例創建內部類實例的時候,會將外部類實例作為初始資源傳入內部類構造過程。這樣我們就可以通過該實例訪問外部類所有的成員信息,包括私有成員。(顯式增加了暴露方法)

至于使用場景,對于那種要高度依賴外部類實例的情況下,定義一個成員內部類則會顯的更加明智。

三、方法內部類

方法內部類,顧名思義,定義在一個方法內部的類。方法內部類相對而言要復雜一些,下面定義一個方法內部類:

public class Out { private String name; public void sayHello(){ class In{ public void showName(){System.out.println('my name is : '+name); } } In in = new In(); in.showName(); }}

我們定義了一個類,在該類中又定義了一個方法sayHello,然而在該方法中我們定義了一個內部類,類In就是一個方法內部類。我們的方法內部類的生命周期不超過包含它的方法的生命周期,也就是說,方法內部類只能在方法中使用。所以在聲明的時候,任何的訪問修飾符都是沒有意義的,于是Java干脆不允許使用任何的訪問修飾符修飾方法內部類。其中還需要注意一點的是,定義和使用時兩回事,別看那一大串定義類的代碼,你實際想要使用該類,就必須new對象,而對于方法內部類而言,只能在方法內部new對象。這就是方法內部類的簡單介紹,下面我們看看其實現原理。

有關方法內部類的實現原理其實是和成員內部類差不太多的,也是在內部類初始化的時候為其傳入一個外部類實例,區別在哪呢?就在于方法內部類是定義在具體方法的內部的,所以該類除了可以通過傳入的外部實例訪問外部類中的字段和方法,對于包含它的方法中被傳入的參數也會隨著外部類實例一起初始化給內部類。

毋庸置疑的是,方法內部類的封裝性比之前介紹的兩種都要完善。所以一般只有在需要高度封裝的時候才會將類定義成方法內部類。

四、匿名內部類

可能內部類的所有分類中,匿名內部類的名號是最大的,也是我們最常用到的,多見于函數式編程,lambda表達式等。下面我們重點看看這個匿名內部類。

匿名內部類就是沒有名字的內部類,在定義完成同時,實例也創建好了,常常和new關鍵字緊密結合。當然,它也不局限于類,也可以是接口 ,可以出現在任何位置。下面我們定義一個匿名內部類:

//首先定義一個普通類public class Out { private String name; private void sayHello(){ System.out.println('my name is :' + name); }}//定義和使用一個匿名內部類public static void main(String [] args){ Out out = new Out(){ @Override public void sayHello(){ System.out.println('my name is cyy'); } public void showName(){ System.out.println('hello single'); } }; out.sayHello();}

從上述代碼中可以很顯然的讓我們看出來,我們的匿名內部類必定是要依托一個父類的,因為它是沒有名字的,無法用一個具體的類型來表示。所以匿名內部類往往都是通過繼承一個父類,重寫或者重新聲明一些成員來實現一個匿名內部類的定義。實際上還是利用了里式轉換原理。

從中我們也可以看到,一個匿名內部類定義的完成就意味著該內部類實例創建的完成。下面我們看看其實現原理:

//反編譯出來的匿名內部類static class Test$1 extends Out{ Out out; public void sayHello() { System.out.println('my name is cyy'); } Test$1(Out o) { this.out = o; }}

其實在看了上述三種內部類的原理之后,反而覺得匿名內部類的實現較為簡單了。主要思路還是將內部類抽離出來,通過初始化傳入外部類的實例以達到對外部類所有成員的訪問。只是在匿名內部類中,被依托的父類不是他的外部類。匿名內部類的主要特點在于,沒有名字,對象只能被使用一次,可以出現在任意位置。所以它的使用場景也是呼之欲出,對于一些對代碼簡潔度有所要求的情況下,可首選匿名內部類。

以上完成了對四種內部類的簡單介紹,對于他們各自實現的原理也都已經介紹過了。其實大致相同,由于jvm對每個類都要求一個單獨的源碼文件,所以編譯階段就完成了分離的操作,但是在分離的過程中又要保持內部類和外部類之間的這種聯系,于是編譯器添加了一些接口保持這種信息共享的結構。使用內部類可以大大增加程序的封裝性,使得代碼整體簡潔度較高。

以上這篇Java內部類的實現原理與可能的內存泄漏說明就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Java
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
性久久久久久久| 香蕉成人啪国产精品视频综合网| 国产精品国产精品国产专区不片| 成人av网址在线| 欧美日韩一级片在线观看| 日韩成人免费电影| aa国产精品| 亚洲精品免费在线播放| 欧美日韩ab| 久久免费视频色| 不卡电影免费在线播放一区| 91精品福利在线一区二区三区| 久久国产精品一区二区| 在线观看免费视频综合| 天使萌一区二区三区免费观看| 国产精品视频免费观看| 亚洲欧美在线高清| 欧美精品激情| 国产日韩精品视频一区| 欧美在线三区| 国产日本一区二区| 欧美高清一区二区| 久久久不卡影院| 91一区一区三区| 2019国产精品| 91色porny在线视频| 国产亚洲一二三区| 色综合天天性综合| 欧美激情视频一区二区三区在线播放| 综合在线观看色| www.亚洲国产| 久久一二三国产| 欧美人妇做爰xxxⅹ性高电影| 久久久国产精品不卡| 丁香六月综合激情| 精品不卡在线视频| 亚洲区一区二| 亚洲视频中文字幕| 久久国产精品亚洲77777| 99热在这里有精品免费| 欧美不卡一区二区| 女生裸体视频一区二区三区| 欧美一级专区| 国产精品无码永久免费888| 欧美精品一卡| 国产精品乱人伦| 欧美日韩综合久久| 亚洲欧美日韩在线| 在线综合亚洲| 婷婷一区二区三区| 欧美日韩精品是欧美日韩精品| 国产一区二区三区黄视频 | 欧美系列一区| 国产精品国产三级国产三级人妇| 日韩午夜电影| 日韩激情av在线| 欧美日韩国产123区| 成人蜜臀av电影| 国产女同互慰高潮91漫画| 伊大人香蕉综合8在线视| 亚洲国产精品欧美一二99| 欧美性感一类影片在线播放| 丰满少妇在线播放bd日韩电影| 国产日韩欧美制服另类| 亚洲麻豆av| 免费在线观看视频一区| 欧美一区二区三区日韩视频| 91美女片黄在线观看| 中文字幕欧美一区| 久久综合电影| 成人综合婷婷国产精品久久 | 无吗不卡中文字幕| 91麻豆精品国产91久久久资源速度| 成人黄色免费短视频| 亚洲男人的天堂在线aⅴ视频| 欧美亚洲图片小说| 91美女视频网站| 天堂av在线一区| 精品少妇一区二区三区日产乱码 | 欧美人xxxx| 欧美午夜在线| 日本不卡一二三| 2019国产精品| 免费久久99精品国产自| eeuss鲁片一区二区三区| 中文字幕亚洲不卡| 欧美在线一二三四区| av毛片久久久久**hd| 夜夜精品浪潮av一区二区三区| 欧美日韩国产一区二区三区地区| 欧美精品啪啪| 蜜桃av一区二区在线观看| 国产欧美日韩在线看| 91成人免费电影| 91看片淫黄大片一级在线观看| 婷婷成人综合网| 国产日韩欧美精品综合| 日本道精品一区二区三区| 欧美破处大片在线视频| 久久电影国产免费久久电影 | 久久亚洲一区| 午夜精品久久99蜜桃的功能介绍| 日本大胆欧美人术艺术动态| 国产精品丝袜在线| 欧美剧情电影在线观看完整版免费励志电影| 亚洲一级网站| 国产精品中文有码| 亚洲国产日韩精品| 欧美激情综合在线| 欧美精品一二三| 国产精品区二区三区日本| 成人avav影音| 同产精品九九九| 国产精品视频在线看| 在线播放欧美女士性生活| 亚洲开发第一视频在线播放| 成人av网站免费| 偷拍一区二区三区四区| 国产精品福利电影一区二区三区四区| 日韩一区二区在线观看| 亚洲一区二区三区午夜| 91在线小视频| 韩国成人在线视频| 亚洲国产精品人人做人人爽| 久久久久97国产精华液好用吗| 欧美体内she精高潮| 国产精品视频久久一区| 欧美精品一卡| 国产91精品久久久久久久网曝门| 日本亚洲免费观看| 亚洲男人天堂av网| 国产亚洲一二三区| 日韩视频免费观看高清完整版| 久久天天综合| 黄色工厂这里只有精品| 成人av在线资源网站| 精品一区二区日韩| 丝袜美腿亚洲综合| 亚洲特黄一级片| 久久综合av免费| 欧美福利一区二区| 欧美综合视频在线观看| 亚洲在线成人| 在线日韩欧美| 欧美特黄视频| av动漫一区二区| 国产九色sp调教91| 麻豆极品一区二区三区| 亚洲一二三专区| 日韩一区在线播放| 日本一区二区免费在线观看视频| 日韩欧美一级精品久久| 欧美日韩不卡一区二区| 色噜噜狠狠成人网p站| 国产农村妇女精品一二区| 一本色道精品久久一区二区三区| 欧美视频观看一区| 欧美日本亚洲| 欧美在线免费| 99久久精品国产麻豆演员表| 国产一区欧美二区| 国产在线不卡一卡二卡三卡四卡| 日本v片在线高清不卡在线观看| 亚洲图片一区二区| 亚洲小说欧美激情另类| 亚洲激情在线激情| 玉足女爽爽91| 一区二区三区欧美视频| 亚洲精品国产精华液| 一区二区三区日韩欧美| 亚洲自拍与偷拍| 亚洲综合av网| 亚洲国产精品影院| 午夜电影网一区| 午夜精品福利一区二区三区蜜桃| 亚洲综合激情另类小说区| 亚洲精品视频一区| 亚洲愉拍自拍另类高清精品| 亚洲天堂精品视频| 一区二区三区在线免费| 亚洲自拍偷拍图区| 亚洲高清在线精品| 日韩中文字幕1| 蜜臂av日日欢夜夜爽一区| 久久国产精品99久久人人澡| 国产在线日韩欧美| 国产**成人网毛片九色 | 久久精品夜色噜噜亚洲a∨| 久久久久久久网| 国产亚洲欧美在线| 国产精品网站在线观看| 亚洲女同女同女同女同女同69| 亚洲一区二区三区激情| 天堂成人国产精品一区| 美日韩一级片在线观看| 国产在线精品不卡| 99这里只有精品| 欧美精品aa| 国产精品乱码| 91久久免费观看|