聊聊Java內(nèi)部類

一.磨嘰磨嘰Java值傳遞與引用傳遞

“在Java里面參數(shù)傳遞都是按值傳遞”
即:按值傳遞是傳遞的值的拷貝,按引用傳遞其實傳遞的是引用的地址值传透,所以統(tǒng)稱按值傳遞胳挎。

簡單的說,基本數(shù)據(jù)類型是按值傳遞的其弊,方法的實參是一個原值的復(fù)本癞己。類對象是按對象的引用地址(內(nèi)存地址)傳遞地址的值,那么在方法內(nèi)對這個對象進行修改是會直接反應(yīng)在原對象上的(或者說這兩個引用指向同一內(nèi)存地址)梭伐。注意String也是值傳遞痹雅。

public static void main(String[] args) { 
    String x = new String("now"); 
    User user = new User("now");
    change(x); 
    System.out.println("1:"+x);
    change(user);
    System.out.println("2:"+user.name);
     User user1 = new User("now");
     System.out.println("3:"+user1 .name);
}
public static void change(String x) { 
    x = "even";
}
public static void change(User x) { 
    x.name = "even";
}
public static void change(User x) { 
    x = new User("even");
}

得出的結(jié)果

1:even
2:even
3:now

二.回歸正題,聊聊Java內(nèi)部類的這些事

Java允許在一個類里面定義另一個類籽御,類里面的類就是內(nèi)部類练慕,也叫做嵌套類

簡單的內(nèi)部類如下:

class OuterClass { 
    class InnerClass{ 
    }
}

經(jīng)常用到的內(nèi)部類:

public class PrivateToOuter { 
    Runnable mRunnable = new Runnable(){ 
        private int x=10; 
        @Override 
        public void run() { 
            System.out.println(x); 
        } 
    }; 
}

以上代碼mRunnable讓人并不覺得是內(nèi)部類,它并不像InnerClass那樣形象技掏,但是其實以下句柄實現(xiàn)一個繼承Runable的類铃将,也就是自定義了一個類,那么明顯它就是一個內(nèi)部類哑梳。其實它是屬于內(nèi)部類一種:匿名內(nèi)部類Anonymous Inner Class

{ 
        private int x=10; 
        @Override 
        public void run() { 
            System.out.println(x); 
        } 
}

內(nèi)部類需要注意的以下幾點:

(1)內(nèi)部類的獲取

內(nèi)部類可以訪問包裝他的外部類的所有劲阎,方法和屬性,包括私有方法鸠真。但是對其他類來說悯仙,它是隱藏的,哪怕對同一個包下面其他類來說吠卷,內(nèi)部類都是隱藏的锡垄,也就是說,如果要訪問內(nèi)部類祭隔,就必須先要得到他的外部包裝類货岭,得到那個句柄之后在new 內(nèi)部類,就可以調(diào)用他的方法了疾渴,如下:

OuterClass outer = new OuterClass();
InnerClass innerClass = outer.new InnerClass();

所以內(nèi)部類是可以很好的解決單繼承的問題千贯。如果對于private在此邏輯為何失效的話,可以查看細(xì)話Java:"失效"的private修飾符

(2)靜態(tài)內(nèi)部類

如果用static 將內(nèi)部內(nèi)靜態(tài)化搞坝,那么內(nèi)部類就只能訪問外部類的靜態(tài)成員變量搔谴,具有局限性

class Out {
    private static int age = 12;
    private int time = 14;
    static class In {
        public void print() {
            System.out.println(age);
        }
    }
}
 
public class Demo {
    public static void main(String[] args) {
        Out.In in = new Out.In();
        in.print();
    }
}

也就是說in只能訪問age,而非time

(3)私有內(nèi)部類

如果一個內(nèi)部類只希望被外部類中的方法操作桩撮,那么可以使用private聲明內(nèi)部類

class Out {
    private int age = 12;
     
    private class In {
        public void print() {
            System.out.println(age);
        }
    }
    public void outPrint() {
        new In().print();
    }
}
 
public class Demo {
    public static void main(String[] args) {
        //此方法無效
        /*
        Out.In in = new Out().new In();
        in.print();
        */
        Out out = new Out();
        out.outPrint();
    }
}

需要特別告訴大家重要的point就是:

在內(nèi)部類構(gòu)造的時候敦第,會將外部類的引用傳遞進來,并且作為內(nèi)部類的一個屬性店量,所以內(nèi)部類會持有一個其外部類的引用芜果。

在Java中,非靜態(tài)的內(nèi)部類和匿名內(nèi)部類都會隱式地持有其外部類的引用垫桂。靜態(tài)的內(nèi)部類不會持有外部類的引用。所以point3中的內(nèi)部類是無法獲取到外部類的成員變量與方法粟按。

回歸到android:

public class SampleActivity extends Activity { 
    private final Handler handler= new Handler() { 
        @Override 
        public void handleMessage(Message msg) { 
            // ...  
        } 
    }
}

這是我們獲取handler實例經(jīng)常所做的操作诬滩,但是回歸到point得知霹粥,handler的匿名內(nèi)部類中有SampleActivity的引用,所以這是有可能導(dǎo)致OOM的隱患疼鸟,比如以下代碼:

public class SampleActivity extends Activity { 
    private final Handler mLeakyHandler = new Handler() { 
        @Override 
        public void handleMessage(Message msg) { // ... } 
    } 
    @Override 
    protected void onCreate(Bundle savedInstanceState) {         
        super.onCreate(savedInstanceState); 
        mLeakyHandler.postDelayed(new Runnable() { 
            @Override 
            public void run() { /* ... */ } 
        }, 1000 * 60 * 10); 
        finish(); 
    }
}

SampleActivity對象已經(jīng)finish后控,但是mLeakyHandler的消息要在10分鐘后執(zhí)行操作,而Handler是一個匿名內(nèi)部類的實例空镜,其持有外面的SampleActivity的引用(而且Runable也是匿名內(nèi)部類浩淘,其內(nèi)部也是持有SampleActivity的引用),所以這導(dǎo)致了SampleActivity無法回收吴攒,進行導(dǎo)致SampleActivity持有的很多資源都無法回收张抄,這就是我們常說的內(nèi)存泄露。解決方法如下:

public class SampleActivity extends Activity { 
    private static class MyHandler extends Handler { 
        private final WeakReference<SampleActivity> mActivity; 
        public MyHandler(SampleActivity activity) { 
            mActivity = new WeakReference<SampleActivity>(activity); 
        } 
        @Override 
        public void handleMessage(Message msg) { 
            SampleActivity activity = mActivity.get(); 
            if (activity != null) { // ... } 
        } 
    } 
    private final MyHandler mHandler = new MyHandler(this); 
    private static final Runnable sRunnable = new Runnable() { 
        @Override 
        public void run() { /* ... */ } 
    };
    @Override 
    protected void onCreate(Bundle savedInstanceState) {     
        super.onCreate(savedInstanceState); 
        mHandler.postDelayed(sRunnable, 1000 * 60 * 10); 
        finish(); 
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末洼怔,一起剝皮案震驚了整個濱河市署惯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌镣隶,老刑警劉巖极谊,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異安岂,居然都是意外死亡轻猖,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門域那,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咙边,“玉大人,你說我怎么就攤上這事琉雳⊙撸” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵翠肘,是天一觀的道長檐束。 經(jīng)常有香客問我,道長束倍,這世上最難降的妖魔是什么被丧? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮绪妹,結(jié)果婚禮上甥桂,老公的妹妹穿的比我還像新娘。我一直安慰自己邮旷,他們只是感情好黄选,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般办陷。 火紅的嫁衣襯著肌膚如雪貌夕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天民镜,我揣著相機與錄音啡专,去河邊找鬼。 笑死制圈,一個胖子當(dāng)著我的面吹牛们童,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鲸鹦,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼慧库,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了亥鬓?” 一聲冷哼從身側(cè)響起完沪,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嵌戈,沒想到半個月后覆积,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡熟呛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年宽档,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片庵朝。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡吗冤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出九府,到底是詐尸還是另有隱情椎瘟,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布侄旬,位于F島的核電站肺蔚,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏儡羔。R本人自食惡果不足惜宣羊,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望汰蜘。 院中可真熱鬧仇冯,春花似錦、人聲如沸族操。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泼舱,卻和暖如春姐赡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背柠掂。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留依沮,地道東北人涯贞。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像危喉,于是被迫代替她去往敵國和親宋渔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容