欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Java內部類與靜態(tài)內部類的區(qū)別

 更新時間:2023年06月26日 09:28:26   作者:單程車票  
本文主要介紹了淺談Java內部類與靜態(tài)內部類的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

本篇記錄一下最近看過的面試問題:內部類與靜態(tài)內部類的區(qū)別?

下面將以較短的篇幅來講解該面試題的知識要點,如果看完題目還沒有想到答案的讀者們可以往下閱讀這篇文章,希望能給你帶來一些收獲。

內部類是什么?

在講解內部類與靜態(tài)內部類的區(qū)別之前,先來看看內部類是什么,為什么 Java 需要內部類?

內部類是指定義在另一個類中的類,它可以訪問外部類的成員變量和方法,并且可以被外部類的其他成員所使用。

為什么需要使用內部類呢?主要有以下兩點原因(這里引用 Java 核心技術卷1 的兩句話):

  • 內部類可以對同一個包中的其他類隱藏。
  • 內部類方法可以訪問定義這個類的作用域中的數(shù)據(jù),包括原本私有的數(shù)據(jù)。

通過代碼來講解內部類的兩個特點

/**
?* 內部類測試
?* @author 單程車票
?*/
public class InnerClassTest {
? ? public static void main(String[] args) {
? ? ? ? Tree tree = new Tree();
? ? ? ? tree.addNode(10);
? ? ? ? // Tree.Node = tree.new Node(10); // 編譯報錯,外部其他類無法使用內部類 Node
? ? }
}
class Tree {
? ? private List<Node> nodes = new ArrayList<>();
? ? // 通過 private 修飾 Node 內部類
? ? private class Node {
? ? ? ? private int value;
? ? ? ? public Node(int val) {
? ? ? ? ? ? value = val;
? ? ? ? }
? ? ? ? public void printLength() {
? ? ? ? ? ? System.out.println("插入節(jié)點值為:" + value);
? ? ? ? ? ? // 內部類成員可以訪問外部類的私有數(shù)據(jù)
? ? ? ? ? ? // 更正規(guī)語法是 Tree.this.nodes.size()
? ? ? ? ? ? System.out.println("當前長度為:" + nodes.size());
? ? ? ? }
? ? }
? ? // 添加 Node 方法(外部類的成員可以使用內部類)
? ? public void addNode(int value) {
? ? ? ? Node node = new Node(value);
? ? ? ? nodes.add(node);
? ? ? ? node.printLength();
? ? }
}

運行結果:

通過上面的代碼可以看到,內部類其實是可以使用 private 和 protected 這兩個訪問權限符來修飾的(外部類是無法通過這兩個訪問權限符修飾的),這也就說明了內部類是可以通過這兩個訪問權限符來控制對外部其他類的隱藏的。

此外,通過上面的代碼還可以清晰的看到外部類 Tree 的方法(成員)可以訪問到外部類的作用域內的變量,包括私有變量。這里的原理是在編譯時內部類會被編譯為 外部類名 + $ + 內部類名(Tree$Node.class)這樣一個類文件,也就是說編譯器對內部類進行了處理,與虛擬機無關。

可以看到,內部類編譯后會生成一個構造器,這個構造器會比源碼多帶上一個參數(shù),這個參數(shù)的類型就是外部類 Tree,并且被保存在 this$0 字段中,到這里也就能說明其實內部類在編譯后會通過構造器將外部類的引用傳遞進來,這樣內部類可以持有外部類對象引用來訪問外部類的變量。
當然,除了以上兩點原因之外,內部類還可以解決 Java 單繼承的問題,由于篇幅問題這里就不再贅述了,有興趣的讀者們可以自行了解。

內部類與靜態(tài)內部類的區(qū)別?

接下來,就應該談談面試題:內部類與靜態(tài)內部類的區(qū)別了,從題目中應該也可以了解到內部類其實細分為成員內部類、局部內部類、匿名內部類和靜態(tài)內部類。
所以,這道面試題其實問的就是非靜態(tài)內部類和靜態(tài)內部類的區(qū)別,也可以理解為成員內部類和靜態(tài)內部類的區(qū)別。關于剩下兩種內部類,由于內容過多且篇幅有限,這里就不做過多說明。

非靜態(tài)內部類與靜態(tài)內部類的區(qū)別?

非靜態(tài)內部類:

  • 實例化:非靜態(tài)內部類的實例化必須依賴于外部類的實例化,即需要先創(chuàng)建外部內實例再創(chuàng)建非靜態(tài)內部類實例(如下面代碼中的 new Inner().new InnerClass())。
  • 訪問外部類的變量和方法:非靜態(tài)內部類可以訪問外部類的所有變量和方法(包括非靜態(tài)和靜態(tài))。
  • 聲明內部類的變量和方法:非靜態(tài)內部類可以聲明非靜態(tài)的變量和方法,但不可以聲明靜態(tài)的變量和方法。

靜態(tài)內部類:

  • 實例化:靜態(tài)內部類的實例化不依賴于外部類的實例化,即可以直接創(chuàng)建靜態(tài)內部類實例(如下面代碼中的 new Inner.StaticInnerClass())。
  • 訪問外部類的變量和方法:靜態(tài)內部類可以訪問外部類的靜態(tài)變量和靜態(tài)方法,但不可以訪問外部類的非靜態(tài)變量和非靜態(tài)方法。
  • 聲明內部類的變量和方法:靜態(tài)內部類可以聲明非靜態(tài)的和靜態(tài)的變量和方法。

給出代碼演示:

/**
?* 測試類
?* @author 單程車票
?*/
public class Inner {
? ? private String field = "外部非靜態(tài)字段";
? ? private static String staticField = "外部靜態(tài)字段";
? ? public void print() {
? ? ? ? System.out.println("外部非靜態(tài)方法");
? ? }
? ? public static void staticPrint() {
? ? ? ? System.out.println("外部靜態(tài)方法");
? ? }
? ? // 非靜態(tài)內部類
? ? public class InnerClass {
? ? ? ? private String innerField = "內部非靜態(tài)字段";
? ? ? ? // private static String innerStaticField = "內部靜態(tài)字段"; // 編譯不通過,不支持 static 聲明
? ? ? ? public void innerPrint() {
? ? ? ? ? ? System.out.println("內部非靜態(tài)方法");
? ? ? ? }
? ? ? ? // 編譯不通過,不支持 static 聲明
? ? ? ? // public static void innerStaticPrint() { System.out.println("內部靜態(tài)方法"); }
? ? ? ? public void read() {
? ? ? ? ? ? System.out.println("讀取非靜態(tài)字段:" + field);
? ? ? ? ? ? System.out.println("讀取靜態(tài)字段:" + staticField);
? ? ? ? ? ? print(); // 調用非靜態(tài)方法
? ? ? ? ? ? staticPrint(); // 調用靜態(tài)方法
? ? ? ? }
? ? }
? ? // 靜態(tài)內部類
? ? public static class StaticInnerClass {
? ? ? ? private String innerField = "內部非靜態(tài)字段";
? ? ? ? private static String innerStaticField = "內部靜態(tài)字段";
? ? ? ? public void innerPrint() {
? ? ? ? ? ? System.out.println("內部非靜態(tài)方法");
? ? ? ? }
? ? ? ? ?public static void innerStaticPrint() {
? ? ? ? ? ? ? System.out.println("內部靜態(tài)方法");
? ? ? ? ?}
? ? ? ? public void read() {
? ? ? ? ? ? // System.out.println("讀取非靜態(tài)字段:" + field); // 編譯不通過,無法讀取非靜態(tài)字段
? ? ? ? ? ? System.out.println("讀取靜態(tài)字段:" + staticField);
? ? ? ? ? ? // print(); // 編譯不通過,無法調用非靜態(tài)方法
? ? ? ? ? ? staticPrint(); // 調用靜態(tài)方法
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
? ? ? ? // 非靜態(tài)內部類實例化,依賴外部類
? ? ? ? Inner.InnerClass innerClass = new Inner().new InnerClass();
? ? ? ? // 靜態(tài)內部類實例化,不依賴外部類
? ? ? ? Inner.StaticInnerClass staticInnerClass = new Inner.StaticInnerClass();
? ? }
}

使用靜態(tài)內部類的時機?

只要內部類不需要訪問外部類對象時,也就是不需要生成外部類對象引用時,就應該使用靜態(tài)內部類。

到此這篇關于淺談Java內部類與靜態(tài)內部類的區(qū)別的文章就介紹到這了,更多相關Java內部類與靜態(tài)內部類內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 解決dubbo錯誤ip及ip亂入問題的方法

    解決dubbo錯誤ip及ip亂入問題的方法

    今天小編就為大家分享一篇關于解決dubbo錯誤ip及ip亂入問題的方法,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • java基于UDP實現(xiàn)在線聊天功能

    java基于UDP實現(xiàn)在線聊天功能

    這篇文章主要為大家詳細介紹了java基于UDP實現(xiàn)在線聊天功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • 解決java.lang.Error: Unresolved compilation problems:問題

    解決java.lang.Error: Unresolved compilation pro

    這篇文章主要介紹了解決java.lang.Error: Unresolved compilation problems:問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • springboot中設置定時任務的三種方法小結

    springboot中設置定時任務的三種方法小結

    在我們開發(fā)項目過程中,經(jīng)常需要定時任務來幫助我們來做一些內容,本文介紹了springboot中設置定時任務的三種方法,主要包括@Scheduled注解,Quartz框架和xxl-job框架的實現(xiàn),感興趣的可以了解一下
    2023-12-12
  • 解決Java中properties文件編碼問題

    解決Java中properties文件編碼問題

    大家好,本篇文章主要講的是解決Java中properties文件編碼問題,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • Sa-Token中的SaSession對象使用學習示例詳解

    Sa-Token中的SaSession對象使用學習示例詳解

    這篇文章主要為大家介紹了Sa-Token中的SaSession對象使用學習示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • 基于SpringMVC對接前端參數(shù)注解

    基于SpringMVC對接前端參數(shù)注解

    這篇文章主要介紹了基于SpringMVC對接前端參數(shù)注解的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Spring Boot2.0中SpringWebContext找不到無法使用的解決方法

    Spring Boot2.0中SpringWebContext找不到無法使用的解決方法

    這篇文章主要給大家介紹了關于Spring Boot2.0中SpringWebContext找不到無法使用的解決方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-12-12
  • JPA如何使用findBy方法自定義查詢

    JPA如何使用findBy方法自定義查詢

    這篇文章主要介紹了JPA如何使用findBy方法自定義查詢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 淺談jvm中的垃圾回收策略

    淺談jvm中的垃圾回收策略

    下面小編就為大家?guī)硪黄獪\談jvm中的垃圾回收策略。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08

最新評論