偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Java:就是要讓你學(xué)會(huì)內(nèi)部類

開(kāi)發(fā) 后端
看了很多源碼,都有用到內(nèi)部類,但是自己以前在生產(chǎn)環(huán)境上,用的確實(shí)少,也有用過(guò)但是很少,所以今天就打算好好的把它從頭到尾的過(guò)一遍。

看了很多源碼,都有用到內(nèi)部類,但是自己以前在生產(chǎn)環(huán)境上,用的確實(shí)少,也有用過(guò)但是很少,所以今天就打算好好的把它從頭到尾的過(guò)一遍。

定義

可以將一個(gè)類的定義放在里另一個(gè)類的內(nèi)部,這就是內(nèi)部類,所謂的內(nèi)部類的概念只是出現(xiàn)在編譯階段,對(duì)于jvm層是沒(méi)有內(nèi)部類這個(gè)概念的。我們可以利用內(nèi)部類來(lái)解決

  •  類的單繼承問(wèn)題,外部類不能再繼承的類可以交給內(nèi)部類繼承
  •  我們可以通過(guò)定義內(nèi)部類來(lái)實(shí)現(xiàn)一個(gè)類私屬于一個(gè)類,實(shí)現(xiàn)更好的封裝性
  •  代碼優(yōu)化:它需要更少的代碼

分類

內(nèi)部類可以分為:

  •  靜態(tài)內(nèi)部類。
  •  非靜態(tài)內(nèi)部類。

非靜態(tài)內(nèi)部類又可以分為:

  •  成員內(nèi)部類。
  •  方法內(nèi)部類。
  •  匿名內(nèi)部類。

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

我感覺(jué)這個(gè)是用的最多的,你比如說(shuō)Redis的key的設(shè)計(jì), 因?yàn)槲覀円虚g拼接:號(hào),所以用靜態(tài)內(nèi)部類去組成不同的key是非常好的,這樣可以讓相同類型的key在同一個(gè)文件目錄下

靜態(tài)內(nèi)部類的定義和普通的靜態(tài)變量或者靜態(tài)方法的定義方法是一樣的,使用static關(guān)鍵字,只不過(guò)這次static是修飾在class上的,一般而言,只有靜態(tài)內(nèi)部類才允許使用static關(guān)鍵字修飾,普通類的定義是不能用static關(guān)鍵字修飾的,這一點(diǎn)需要注意一下。

下面定義一個(gè)靜態(tài)內(nèi)部類: 

  1. public class Out {  
  2.     private static String name;  
  3.     private int age;  
  4.     public static class In{  
  5.         private int age;  
  6.         public void sayHello(){  
  7.             System.out.println("my name is : "+name);  
  8.             //--編譯報(bào)錯(cuò)---  
  9.             //System.out.println("my age is :"+ age);  
  10.         } 
  11.      }  

在上述代碼中,In這個(gè)類就是一個(gè)靜態(tài)內(nèi)部類。我們說(shuō)內(nèi)部類是可以訪問(wèn)外部類的私有字段和私有方法的,對(duì)于靜態(tài)內(nèi)部類,它遵循一致的原則,只能訪問(wèn)外部類的靜態(tài)成員。

上述代碼中,外部類的非靜態(tài)私有字段age在靜態(tài)內(nèi)部類中是不允許訪問(wèn)的,而靜態(tài)字段name則是可訪問(wèn)的。下面我們看,如何創(chuàng)建一個(gè)靜態(tài)內(nèi)部類的實(shí)例對(duì)象。 

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

使用場(chǎng)景,一般來(lái)說(shuō),對(duì)于和外部類聯(lián)系緊密但是并不依賴于外部類實(shí)例的情況下,可以考慮定義成靜態(tài)內(nèi)部類。下面我們看稍顯復(fù)雜的成員內(nèi)部類。

成員內(nèi)部類

我們說(shuō)了,四種不同類型的內(nèi)部類都各自有各自的使用場(chǎng)景,靜態(tài)內(nèi)部類適合于那種和外部類關(guān)系密切但是并不依賴外部類實(shí)例的情況。但是對(duì)于需要和外部類實(shí)例相關(guān)聯(lián)的情況下,可以選擇將內(nèi)部類定義成成員內(nèi)部類。

以下代碼定義了一個(gè)簡(jiǎn)單的成員內(nèi)部類: 

  1. public class Out {  
  2.     private String name;  
  3.     public void showName(){  
  4.         System.out.println("my name is : "+name);  
  5.     }  
  6.     public class In{  
  7.         public void sayHello(){  
  8.             System.out.println(name);  
  9.             Out.this.showName();  
  10.         }  
  11.     }  

以上定義了一個(gè)簡(jiǎn)單的內(nèi)部類In,我們的成員內(nèi)部類可以直接訪問(wèn)外部類的成員字段和成員方法,因?yàn)樗顷P(guān)聯(lián)著一個(gè)外部類實(shí)例的。下面我們看看在外部是如何創(chuàng)建該內(nèi)部類實(shí)例的。 

  1. public static void main(String [] args){  
  2.     Out out = new Out();  
  3.     out.setName("六脈神劍")  
  4.     Out.In in = out.new In();  
  5.     in.sayHello();  

因?yàn)槌蓡T內(nèi)部類是關(guān)聯(lián)著一個(gè)具體的外部類實(shí)例的,所以它的實(shí)例創(chuàng)建必然是由外部類實(shí)例來(lái)創(chuàng)建的。

對(duì)于實(shí)例的創(chuàng)建,我們只需要記住即可,成員內(nèi)部類的實(shí)例創(chuàng)建需要關(guān)聯(lián)外部類實(shí)例對(duì)象,靜態(tài)內(nèi)部類實(shí)例創(chuàng)建相對(duì)簡(jiǎn)單。下面我們主要看看在編譯階段編譯器是如何保持內(nèi)部類對(duì)外部類成員信息可訪問(wèn)的。

使用場(chǎng)景,對(duì)于那種要高度依賴外部類實(shí)例的情況下,定義一個(gè)成員內(nèi)部類則會(huì)顯的更加明智。

方法內(nèi)部類

方法內(nèi)部類,顧名思義,定義在一個(gè)方法內(nèi)部的類。方法內(nèi)部類相對(duì)而言要復(fù)雜一些,下面定義一個(gè)方法內(nèi)部類: 

  1. public class Out {  
  2.     private String name;  
  3.     public void sayHello(){  
  4.         class In{  
  5.             public void showName(){  
  6.                 System.out.println("my name is : "+name);  
  7.             }  
  8.         }  
  9.         In in = new In();  
  10.         in.showName();  
  11.     }  

我們定義了一個(gè)類,在該類中又定義了一個(gè)方法sayHello,然而在該方法中我們定義了一個(gè)內(nèi)部類,類In就是一個(gè)方法內(nèi)部類。我們的方法內(nèi)部類的生命周期不超過(guò)包含它的方法的生命周期,也就是說(shuō),方法內(nèi)部類只能在方法中使用。所以在聲明的時(shí)候,任何的訪問(wèn)修飾符都是沒(méi)有意義的,于是Java干脆不允許使用任何的訪問(wèn)修飾符修飾方法內(nèi)部類。

其中還需要注意一點(diǎn)的是,定義和使用時(shí)兩回事,別看那一大串定義類的代碼,你實(shí)際想要使用該類,就必須new對(duì)象,而對(duì)于方法內(nèi)部類而言,只能在方法內(nèi)部new對(duì)象。這就是方法內(nèi)部類的簡(jiǎn)單介紹,下面我們看看其實(shí)現(xiàn)原理。

有關(guān)方法內(nèi)部類的實(shí)現(xiàn)原理其實(shí)是和成員內(nèi)部類差不太多的,也是在內(nèi)部類初始化的時(shí)候?yàn)槠鋫魅胍粋€(gè)外部類實(shí)例,區(qū)別在哪呢?就在于方法內(nèi)部類是定義在具體方法的內(nèi)部的,所以該類除了可以通過(guò)傳入的外部實(shí)例訪問(wèn)外部類中的字段和方法,對(duì)于包含它的方法中被傳入的參數(shù)也會(huì)隨著外部類實(shí)例一起初始化給內(nèi)部類。

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

匿名內(nèi)部類

可能內(nèi)部類的所有分類中,匿名內(nèi)部類的名號(hào)是最大的,也是我們最常用到的,多見(jiàn)于函數(shù)式編程,lambda表達(dá)式等。下面我們重點(diǎn)看看這個(gè)匿名內(nèi)部類。

匿名內(nèi)部類就是沒(méi)有名字的內(nèi)部類,在定義完成同時(shí),實(shí)例也創(chuàng)建好了,常常和new關(guān)鍵字緊密結(jié)合。當(dāng)然,它也不局限于類,也可以是接口,可以出現(xiàn)在任何位置。

下面我們定義一個(gè)匿名內(nèi)部類:

如果您必須重寫類或接口的方法,則應(yīng)該使用它??梢酝ㄟ^(guò)兩種方式創(chuàng)建Java匿名內(nèi)部類 

  1. //首先定義一個(gè)普通類  
  2. public class Out {  
  3.     private String name;  
  4.     public void sayHello(){  
  5.         System.out.println("my name is :" + name);  
  6.     }  

  1. //定義和使用一個(gè)匿名內(nèi)部類  
  2. public static void main(String [] args){  
  3.     Out out = new Out(){  
  4.         @Override  
  5.         public void sayHello(){  
  6.             System.out.println("my name is cyy");  
  7.         }  
  8.         public void showName(){  
  9.             System.out.println("hello single");  
  10.         }  
  11.     };  
  12.     out.sayHello();  

從上述代碼中可以很顯然的讓我們看出來(lái),我們的匿名內(nèi)部類必定是要依托一個(gè)父類的,因?yàn)樗菦](méi)有名字的,無(wú)法用一個(gè)具體的類型來(lái)表示。所以匿名內(nèi)部類往往都是通過(guò)繼承一個(gè)父類,重寫或者重新聲明一些成員來(lái)實(shí)現(xiàn)一個(gè)匿名內(nèi)部類的定義。實(shí)際上還是利用了里式轉(zhuǎn)換原理。

其實(shí)在看了上述三種內(nèi)部類的原理之后,反而覺(jué)得匿名內(nèi)部類的實(shí)現(xiàn)較為簡(jiǎn)單了。主要思路還是將內(nèi)部類抽離出來(lái),通過(guò)初始化傳入外部類的實(shí)例以達(dá)到對(duì)外部類所有成員的訪問(wèn)。只是在匿名內(nèi)部類中,被依托的父類不是他的外部類。

匿名內(nèi)部類的主要特點(diǎn)在于,沒(méi)有名字,對(duì)象只能被使用一次,可以出現(xiàn)在任意位置。所以它的使用場(chǎng)景也是呼之欲出,對(duì)于一些對(duì)代碼簡(jiǎn)潔度有所要求的情況下,可首選匿名內(nèi)部類。

總結(jié)

以上完成了對(duì)四種內(nèi)部類的簡(jiǎn)單介紹,對(duì)于他們各自實(shí)現(xiàn)的原理也都已經(jīng)介紹過(guò)了。其實(shí)大致相同,由于jvm對(duì)每個(gè)類都要求一個(gè)單獨(dú)的源碼文件,所以編譯階段就完成了分離的操作,但是在分離的過(guò)程中又要保持內(nèi)部類和外部類之間的這種聯(lián)系,于是編譯器添加了一些接口保持這種信息共享的結(jié)構(gòu)。

使用內(nèi)部類可以大大增加程序的封裝性,使得代碼整體簡(jiǎn)潔度較高。

講完這個(gè)后面的函數(shù)式接口 引用就好講一點(diǎn)了

結(jié)尾

內(nèi)部類就講那么多,希望大家以后看源碼會(huì)輕松點(diǎn),哈哈 

 

責(zé)任編輯:龐桂玉 來(lái)源: Java知音
相關(guān)推薦

2020-12-14 10:23:23

Java內(nèi)部類外部類

2020-09-09 12:55:28

Nginx高并發(fā)性能

2020-09-10 09:31:34

Nginx HTTP代理服務(wù)器

2020-01-15 11:14:21

Java算法排序

2011-03-29 14:11:15

內(nèi)部類

2022-11-03 07:07:49

函數(shù)Pandascsv

2009-06-11 13:08:29

Java內(nèi)部類Java編程思想

2023-10-19 13:24:00

Java工具

2023-03-06 07:53:36

JavaN種內(nèi)部類

2011-07-21 15:44:33

Java內(nèi)部類

2009-07-29 09:18:49

Java內(nèi)部類

2012-04-17 11:21:50

Java

2020-09-21 07:00:42

Java內(nèi)部類接口

2015-12-08 09:05:41

Java內(nèi)部類

2021-05-24 10:50:10

Git命令Linux

2009-08-26 18:00:07

C#內(nèi)部類

2024-01-19 08:25:38

死鎖Java通信

2020-01-12 19:10:30

Java程序員數(shù)據(jù)

2010-02-05 15:32:33

Java內(nèi)部類

2009-07-22 16:13:40

iBATIS用法SqlMapTempl
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)