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

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

 更新時(shí)間:2023年06月26日 09:28:26   作者:?jiǎn)纬誊嚻? 
本文主要介紹了淺談Java內(nèi)部類與靜態(tài)內(nèi)部類的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

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

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

內(nèi)部類是什么?

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

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

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

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

通過(guò)代碼來(lái)講解內(nèi)部類的兩個(gè)特點(diǎn)

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

運(yùn)行結(jié)果:

通過(guò)上面的代碼可以看到,內(nèi)部類其實(shí)是可以使用 private 和 protected 這兩個(gè)訪問(wèn)權(quán)限符來(lái)修飾的(外部類是無(wú)法通過(guò)這兩個(gè)訪問(wèn)權(quán)限符修飾的),這也就說(shuō)明了內(nèi)部類是可以通過(guò)這兩個(gè)訪問(wèn)權(quán)限符來(lái)控制對(duì)外部其他類的隱藏的。

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

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

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

接下來(lái),就應(yīng)該談?wù)劽嬖囶}:內(nèi)部類與靜態(tài)內(nèi)部類的區(qū)別了,從題目中應(yīng)該也可以了解到內(nèi)部類其實(shí)細(xì)分為成員內(nèi)部類、局部?jī)?nèi)部類、匿名內(nèi)部類和靜態(tài)內(nèi)部類。
所以,這道面試題其實(shí)問(wèn)的就是非靜態(tài)內(nèi)部類和靜態(tài)內(nèi)部類的區(qū)別,也可以理解為成員內(nèi)部類和靜態(tài)內(nèi)部類的區(qū)別。關(guān)于剩下兩種內(nèi)部類,由于內(nèi)容過(guò)多且篇幅有限,這里就不做過(guò)多說(shuō)明。

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

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

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

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

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

給出代碼演示:

/**
?* 測(cè)試類
?* @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)內(nèi)部類
? ? public class InnerClass {
? ? ? ? private String innerField = "內(nèi)部非靜態(tài)字段";
? ? ? ? // private static String innerStaticField = "內(nèi)部靜態(tài)字段"; // 編譯不通過(guò),不支持 static 聲明
? ? ? ? public void innerPrint() {
? ? ? ? ? ? System.out.println("內(nèi)部非靜態(tài)方法");
? ? ? ? }
? ? ? ? // 編譯不通過(guò),不支持 static 聲明
? ? ? ? // public static void innerStaticPrint() { System.out.println("內(nèi)部靜態(tài)方法"); }
? ? ? ? public void read() {
? ? ? ? ? ? System.out.println("讀取非靜態(tài)字段:" + field);
? ? ? ? ? ? System.out.println("讀取靜態(tài)字段:" + staticField);
? ? ? ? ? ? print(); // 調(diào)用非靜態(tài)方法
? ? ? ? ? ? staticPrint(); // 調(diào)用靜態(tài)方法
? ? ? ? }
? ? }
? ? // 靜態(tài)內(nèi)部類
? ? public static class StaticInnerClass {
? ? ? ? private String innerField = "內(nèi)部非靜態(tài)字段";
? ? ? ? private static String innerStaticField = "內(nèi)部靜態(tài)字段";
? ? ? ? public void innerPrint() {
? ? ? ? ? ? System.out.println("內(nèi)部非靜態(tài)方法");
? ? ? ? }
? ? ? ? ?public static void innerStaticPrint() {
? ? ? ? ? ? ? System.out.println("內(nèi)部靜態(tài)方法");
? ? ? ? ?}
? ? ? ? public void read() {
? ? ? ? ? ? // System.out.println("讀取非靜態(tài)字段:" + field); // 編譯不通過(guò),無(wú)法讀取非靜態(tài)字段
? ? ? ? ? ? System.out.println("讀取靜態(tài)字段:" + staticField);
? ? ? ? ? ? // print(); // 編譯不通過(guò),無(wú)法調(diào)用非靜態(tài)方法
? ? ? ? ? ? staticPrint(); // 調(diào)用靜態(tài)方法
? ? ? ? }
? ? }
? ? public static void main(String[] args) {
? ? ? ? // 非靜態(tài)內(nèi)部類實(shí)例化,依賴外部類
? ? ? ? Inner.InnerClass innerClass = new Inner().new InnerClass();
? ? ? ? // 靜態(tài)內(nèi)部類實(shí)例化,不依賴外部類
? ? ? ? Inner.StaticInnerClass staticInnerClass = new Inner.StaticInnerClass();
? ? }
}

使用靜態(tài)內(nèi)部類的時(shí)機(jī)?

只要內(nèi)部類不需要訪問(wèn)外部類對(duì)象時(shí),也就是不需要生成外部類對(duì)象引用時(shí),就應(yīng)該使用靜態(tài)內(nèi)部類。

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

相關(guān)文章

  • 解決dubbo錯(cuò)誤ip及ip亂入問(wèn)題的方法

    解決dubbo錯(cuò)誤ip及ip亂入問(wèn)題的方法

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

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

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

    解決java.lang.Error: Unresolved compilation pro

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

    springboot中設(shè)置定時(shí)任務(wù)的三種方法小結(jié)

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

    解決Java中properties文件編碼問(wèn)題

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

    Sa-Token中的SaSession對(duì)象使用學(xué)習(xí)示例詳解

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

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

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

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

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

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

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

    淺談jvm中的垃圾回收策略

    下面小編就為大家?guī)?lái)一篇淺談jvm中的垃圾回收策略。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08

最新評(píng)論