成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java:就是要讓你學會內部類

開發 后端
看了很多源碼,都有用到內部類,但是自己以前在生產環境上,用的確實少,也有用過但是很少,所以今天就打算好好的把它從頭到尾的過一遍。

看了很多源碼,都有用到內部類,但是自己以前在生產環境上,用的確實少,也有用過但是很少,所以今天就打算好好的把它從頭到尾的過一遍。

定義

可以將一個類的定義放在里另一個類的內部,這就是內部類,所謂的內部類的概念只是出現在編譯階段,對于jvm層是沒有內部類這個概念的。我們可以利用內部類來解決

  •  類的單繼承問題,外部類不能再繼承的類可以交給內部類繼承
  •  我們可以通過定義內部類來實現一個類私屬于一個類,實現更好的封裝性
  •  代碼優化:它需要更少的代碼

分類

內部類可以分為:

  •  靜態內部類。
  •  非靜態內部類。

非靜態內部類又可以分為:

  •  成員內部類。
  •  方法內部類。
  •  匿名內部類。

靜態內部類

我感覺這個是用的最多的,你比如說Redis的key的設計, 因為我們要中間拼接:號,所以用靜態內部類去組成不同的key是非常好的,這樣可以讓相同類型的key在同一個文件目錄下

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

下面定義一個靜態內部類: 

  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.             //--編譯報錯---  
  9.             //System.out.println("my age is :"+ age);  
  10.         } 
  11.      }  

在上述代碼中,In這個類就是一個靜態內部類。我們說內部類是可以訪問外部類的私有字段和私有方法的,對于靜態內部類,它遵循一致的原則,只能訪問外部類的靜態成員。

上述代碼中,外部類的非靜態私有字段age在靜態內部類中是不允許訪問的,而靜態字段name則是可訪問的。下面我們看,如何創建一個靜態內部類的實例對象。 

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

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

成員內部類

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

以下代碼定義了一個簡單的成員內部類: 

  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.     }  

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

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

因為成員內部類是關聯著一個具體的外部類實例的,所以它的實例創建必然是由外部類實例來創建的。

對于實例的創建,我們只需要記住即可,成員內部類的實例創建需要關聯外部類實例對象,靜態內部類實例創建相對簡單。下面我們主要看看在編譯階段編譯器是如何保持內部類對外部類成員信息可訪問的。

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

方法內部類

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

  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.     }  

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

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

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

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

匿名內部類

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

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

下面我們定義一個匿名內部類:

如果您必須重寫類或接口的方法,則應該使用它。可以通過兩種方式創建Java匿名內部類 

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

  1. //定義和使用一個匿名內部類  
  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();  

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

其實在看了上述三種內部類的原理之后,反而覺得匿名內部類的實現較為簡單了。主要思路還是將內部類抽離出來,通過初始化傳入外部類的實例以達到對外部類所有成員的訪問。只是在匿名內部類中,被依托的父類不是他的外部類。

匿名內部類的主要特點在于,沒有名字,對象只能被使用一次,可以出現在任意位置。所以它的使用場景也是呼之欲出,對于一些對代碼簡潔度有所要求的情況下,可首選匿名內部類。

總結

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

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

講完這個后面的函數式接口 引用就好講一點了

結尾

內部類就講那么多,希望大家以后看源碼會輕松點,哈哈 

 

責任編輯:龐桂玉 來源: Java知音
相關推薦

2020-12-14 10:23:23

Java內部類外部類

2020-09-09 12:55:28

Nginx高并發性能

2020-09-10 09:31:34

Nginx HTTP代理服務器

2020-01-15 11:14:21

Java算法排序

2011-03-29 14:11:15

內部類

2023-03-06 07:53:36

JavaN種內部類

2009-06-11 13:08:29

Java內部類Java編程思想

2022-11-03 07:07:49

函數Pandascsv

2023-10-19 13:24:00

Java工具

2011-07-21 15:44:33

Java內部類

2015-12-08 09:05:41

Java內部類

2009-07-29 09:18:49

Java內部類

2012-04-17 11:21:50

Java

2020-09-21 07:00:42

Java內部類接口

2024-01-19 08:25:38

死鎖Java通信

2020-01-12 19:10:30

Java程序員數據

2009-08-26 18:00:07

C#內部類

2021-05-24 10:50:10

Git命令Linux

2020-10-29 08:31:15

Java同步回調編程語言

2011-03-15 10:41:05

內部類
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美久久久久久久久 | 天天搞天天操 | 中文字幕一区二区三区精彩视频 | 欧美综合一区 | 亚洲精品黄 | 亚洲视频免费在线看 | 日本a级大片 | 国产精品视频在线观看 | 极品久久| 国产成人精品一区二区三区在线 | 香蕉久久av | 国产一在线观看 | 欧美高清视频一区 | 亚洲久视频| 亚洲国产精品久久久久婷婷老年 | 毛片一区二区三区 | 最新一级毛片 | 欧美男男videos | 国产精品91久久久久久 | 国产成人精品一区二区三区在线 | 日日摸夜夜添夜夜添精品视频 | 久久777| 九九热re| 久久99精品久久久 | 中文字幕乱码一区二区三区 | 在线播放中文字幕 | 亚洲 自拍 另类 欧美 丝袜 | 欧美mv日韩mv国产网站91进入 | 亚洲一区中文 | 亚洲色图网址 | 日操夜操 | 亚洲高清视频在线 | av官网在线 | 日韩免费视频一区二区 | 午夜视频免费在线 | 99精品视频在线观看 | 99久久国产综合精品麻豆 | 欧美一级片在线观看 | 欧美精品一级 | 亚洲精品成人 | 久久久一区二区 |