fegin需要實現類_【第24條】靜態成員類優于非靜態成員類

第24條

靜態成員類優于非靜態成員類

嵌套類(nested class)是指定義在另一個類的內部的類。嵌套類存在的目的應該只是為它的外圍類(enclosing class)提供服務。如果嵌套類將來可能會用于其他的某個環境中,它就應該是頂層類(top-level class)。嵌套類有四種:靜態成員類(static member class)、非靜態成員類(nonstatic member class)、匿名類(anonymous class)和局部類(local class)。除了第一種之外,其他三種都稱為內部類(inner class) 。本條目將告訴你什么時候應該使用哪種嵌套類,以及這樣做的原因。

靜態成員類是最簡單的一種嵌套類。最好把它看作是普通的類,只是碰巧被聲明在另一個類的內部而已,它可以訪問外圍類的所有成員,包括那些聲明為私有的成員。靜態成員類是外圍類的一個靜態成員,與其他的靜態成員一樣,也遵守同樣的可訪問性規則。如果它被聲明為私有的,它就只能在外圍類的內部才可以被訪問,等等。

靜態成員類的一種常見用法是作為公有的輔助類,只有與它的外部類一起使用才有意義。例如,以枚舉為例,它描述了計算器支持的各種操作(詳見第34條)。Operation枚舉應該是Calculator類的公有靜態成員類,之后Calculator類的客戶端就可以用諸如 Calculator.Operation.PLUS 和 Calculator.Operation.MINUS 這樣的名稱來引用這些操作。

從語法上講,靜態成員類和非靜態成員類之間唯一的區別是,靜態成員類的聲明中包含修飾符static。盡管它們的語法非常相似,但是這兩種嵌套類有很大的不同。非靜態成員類的每個實例都隱含地與外圍類的一個外圍實例(enclosing instance)相關聯。在非靜態成員類的實例方法內部,可以調用外圍實例上的方法,或者利用修飾過的this(qualified this)構造獲得外圍實例的引用。如果嵌套類的實例可以在它外圍類的實例之外獨立存在,這個嵌套類就必須是靜態成員類:在沒有外圍實例的情況下,要想創建非靜態成員類的實例是不可能的。

當非靜態成員類的實例被創建的時候,它和外圍實例之間的關聯關系也隨之被建立起來;而且,這種關聯關系以后不能被修改。通常情況下,當在外圍類的某個實例方法的內部調用非靜態成員類的構造器時,這種關聯關系被自動建立起來。使用表達式enclosingInstance.newMemberClass(args)來手工建立這種關聯關系也是有可能的,但是很少使用。正如你所預料的那樣,這種關聯關系需要消耗非靜態成員類實例的空間,并且會增加構造的時間開銷。

非靜態成員類的一種常見用法是定義一個Adapter,它允許外部類的實例被看作是另一個不相關的類的實例。例如,Map接口的實現往往使用非靜態成員類來實現它們的集合視圖(collection view),這些集合視圖是由Map的keySet、entrySet和values方法返回的。同樣地,諸如Set和List這種集合接口的實現往往也使用非靜態成員類來實現它們的迭代器(iterator):

// Typical use of a nonstatic member classpublic class MySet<E> extends AbstractSet<E> {  ... // Buik of the class omitted  ?Override public Iterator iterator() (    return new Mylterator();  }  private class Mylterator implements Iterator<E> {  }}

如果聲明成員類不要求訪問外圍實例,就要始終把修飾符static放在它的聲明中,使它成為靜態成員類,而不是非靜態成員類。如果省略了static修飾符,則每個實例都將包含一個額外的指向外圍對象的引用。如前所述,保存這份引用要消耗時間和空間,并且會導致外圍實例在符合垃圾回收(詳見第7條)時卻仍然得以保留。由此造成的內存泄漏可能是災難性的。但是常常難以發現,因為這個引用是不可見的。

私有靜態成員類的一種常見用法是代表外圍類所代表的對象的組件。以Map實例為例,它把鍵(key)和值(value)關聯起來。許多Map實現的內部都有一個Entry對象,對應于Map中的每個鍵-值對。雖然每個entry都與一個Map關聯,但是entry上的方法(getKey、getValue和setValue)并不需要訪問該Map。因此,使用非靜態成員類來表示entry是很浪費的:私有的靜態成員類是最佳的選擇。如果不小心漏掉了entry聲明中的static修飾符,該Map仍然可以工作,但是每個entry中將會包含一個指向該Map的引用,這樣就浪費了空間和時間。

如果相關的類是導出類的公有或受保護的成員,毫無疑問,在靜態和非靜態成員類之間做出正確的選擇是非常重要的。在這種情況下,該成員類就是導出的API元素,在后續的發行版本中,如果不違反向后兼容性,就無法從非靜態成員類變為靜態成員類。

顧名思義,匿名類是沒有名字的。它不是外圍類的一個成員。它并不與其他的成員一起被聲明,而是在使用的同時被聲明和實例化。匿名類可以出現在代碼中任何允許存在表達式的地方。當且僅當匿名類出現在非靜態的環境中時,它才有外圍實例。但是即使它們出現在靜態的環境中,也不可能擁有任何靜態成員,而是擁有常數變量(constant variable),常數變量是final基本類型,或者被初始化成常量表達式的字符串域。

匿名類的運用受到諸多的限制。除了在它們被聲明的時候之外,是無法將它們實例化的。不能執行instanceof測試,或者做任何需要命名類的其他事情。無法聲明一個匿名類來實現多個接口,或者擴展一個類,并同時擴展類和實現接口。除了從超類型中繼承得到之外,匿名類的客戶端無法調用任何成員。由于匿名類出現在表達式中,它們必須保持簡短(大約10行或者更少),否則會影響程序的可讀性。

在Java中增加lambda(詳見第6章)之前,匿名類是動態地創建小型函數對象(function object)和過程對象(process object)的最佳方式,但是現在會優先選擇lambda(詳見第42條)。匿名類的另一種常見用法是在靜態工廠方法的內部(參見第20條中的intArrayAsList方法)。

局部類是四種嵌套類中使用最少的類。在任何“可以聲明局部變量”的地方,都可以聲明局部類,并且局部類也遵守同樣的作用域規則。局部類與其他三種嵌套類中的每一種都有一些共同的屬性。與成員類一樣,局部類有名字,可以被重復使用。與匿名類一樣,只有當局部類是在非靜態環境中定義的時候,才有外圍實例,它們也不能包含靜態成員。與匿名類一樣,它們必須非常簡短,以便不會影響可讀性。

總而言之,共有四種不同的嵌套類,每一種都有自己的用途。如果一個嵌套類需要在單個方法之外仍然是可見的,或者它太長了,不適合放在方法內部,就應該使用成員類。如果成員類的每個實例都需要一個指向其外圍實例的引用,就要把成員類做成非靜態的;否則,就做成靜態的。假設這個嵌套類屬于一個方法的內部,如果你只需要在一個地方創建實例,并且已經有了一個預置的類型可以說明這個類的特征,就要把它做成匿名類;否則,就做成局部類。

掃描二維碼

獲取更多精彩

Java樂分享

b830a14227a6d72050246452121aeeff.png

?92828ef5065e8f93f728f11401755e42.png感謝支持92828ef5065e8f93f728f11401755e42.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537588.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537588.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537588.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

.h與.cpp

本質上沒什么區別。 cpp:c plus plus,就表示為c原文件。 .h文件實現的功能是聲明.cpp文件中需要使用的變量、函數及宏定義等。 .h文件就像是一個接口&#xff0c;具體的實現可以在.cpp中&#xff0c;也可以在.h中。轉載于:https://www.cnblogs.com/keguniang/p/9877581.html

Springboot 多線程的使用

直接上代碼 線程配置類 package zengmg.nbpi.com.thread;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework…

vlookup函數練習_為什么職場要學excel函數?看這個案例演示:自動計算快遞價格...

在上一篇文章里面&#xff0c;我們講了如何整理完成一個規范化的表格&#xff0c;以便于下一步的函數計算。最初的信息內容如圖所示。經過整理&#xff0c;我們得到了表2這樣的規范化表格。現在&#xff0c;我們就通過表2來實現快遞費用自動計算&#xff0c;最終實現圖中這樣的…

%@ taglib prefix=c uri=http://java.sun.com/jsp/jstl/core %會報錯

有些時候&#xff0c;<% taglib prefix"c" uri"http://java.sun.com/jsp/jstl/core" %>會報錯&#xff0c;錯誤提示為&#xff1a; Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core" 主要原因是缺少 jst…

藍牙芯片排行_7月TWS 全球品牌出貨量排行榜出爐

數據鑄造影響力撰文 / 旭日大數據編輯 / 柏序旭日大數據公布了2020年7月全球TWS品牌銷量排行榜&#xff0c;與上期數據相比&#xff0c;全球品牌七排名TOP20汰換率為15%&#xff0c;其中DOSS&#xff0c;萬魔、BOSE跌出前20&#xff0c;廣州由我&#xff0c;Tzumi登榜&…

project 打印的時候上面的表格和下面的圖例中間有個很大的空白,這塊東西怎么能去掉呢?

“打印預覽”的“頁面設置”里面&#xff0c;“頁面”選項卡里的“縮放”項設為1頁寬&#xff0c;1頁高就可以了&#xff0c; 當然如果你的任務項比較少的話&#xff0c;怎么調也不容易去掉下面的空白 操作如下圖&#xff08;下圖的任務太少&#xff0c;去不掉空白的&#xf…

加密機工作原理_端子機壓力檢測裝置工作原理

上期我們介紹了端子機壓力管理裝置的使用常識&#xff0c;這期我們介紹端子機壓力管理裝置的工作原理&#xff0c;端子機壓接管理裝置&#xff0c;有單通道壓力監測和雙通道壓力監測二種&#xff0c;雙通道壓力監測裝置&#xff0c;一般用于雙頭端子壓接機上&#xff0c;一臺主…

win10解決java多版本java -version問題

電腦環境 先安裝了Jdk8&#xff0c;后安裝了jdk11.&#xff08;發現Jdk11沒有單獨的jre&#xff0c;官網也不提供下載&#xff0c;集成在一起了&#xff09; Java -version 將環境變量切換為 JDK11 后 javac -version 是 java編譯環境是jdk11了&#xff0c;但 java -versio…

vs設計窗口不見了_碳纖維的巔峰:VS沛納海616V3

各位朋友&#xff0c;你們好&#xff01;歡迎大家關注XYZ腕表俱樂部。專注腕表資訊&#xff0c;致力于做腕表拆解測評&#xff0c;為大家普及分享有價值的腕表知識&#xff0c;真正讓大家實實在在透明玩表。想了解更多&#xff0c;歡迎搜索&#xff1a;XYZ腕表俱樂部。可以讓您…

CSharpGL(49)試水OpenGL軟實現

CSharpGL(49)試水OpenGL軟實現 CSharpGL迎來了第49篇。本篇內容是用C#編寫一個OpenGL的軟實現。暫且將其命名為SoftGL。 目前已經實現了由Vertex Shader和Fragment Shader組成的Pipeline&#xff0c;其效果與顯卡支持的OpenGL實現幾乎相同。下圖左是常規OpenGL渲染的結果&#…

SonarQube結合IDEA實現代碼檢測

環境準備 1.SonarQube下載&#xff1a;https://www.sonarqube.org/downloads/ 建議用最新版本&#xff0c;SonarQube與idea的結合 需要SonarQube很多插件&#xff0c;需要借助idea的SonarLint 插件。 不同的SonarQube版本&#xff0c;有不同的插件版本 idea的SonarLint 插件…

二維小波變換_【外文文獻速讀】實時二維水波模擬

題目&#xff1a;Water surface wavelets 作者&#xff1a;Stefan Jeschke&#xff0c; Tom?Sk?ivan&#xff0c; MatthiasMller-Fischer&#xff0c; Nuttapong Chentanez&#xff0c; Miles Macklin&#xff0c; Chris Wojtan

技術開發(委托)合同怎么寫?

一直基于寧波市科技局備案合同模板簽訂合同&#xff0c;并完成科技局備案工作&#xff0c;成功了N次&#xff0c;直接分享模板&#xff0c;該模板通過了法務審核&#xff0c;財務審核&#xff0c;只需要批示修改相關內容即可&#xff0c;一份技術開發委托合同&#xff0c;十幾分…

最常用的15個前端表單驗證JS正則表達式

2019獨角獸企業重金招聘Python工程師標準>>> 在表單驗證中&#xff0c;使用正則表達式來驗證正確與否是一個很頻繁的操作&#xff0c;本文收集整理了15個常用的JavaScript正則表達式&#xff0c;其中包括用戶名、密碼強度、整數、數字、電子郵件地址&#xff08;Ema…

程序員個人外包合同怎么寫?

分享一份工作上經常用到的個人外包合同協議&#xff0c;該協議通過了法務與財務審核&#xff0c;兼顧甲乙雙方利益&#xff0c;程序員接私活必備&#xff01;&#xff01;&#xff01;&#xff01; ---需要電子word版&#xff0c;請關注--------- 回復&#xff1a;個人外包合同…

rocketmq新擴容的broker沒有tps_深入研究RocketMQ消費者是如何獲取消息的

前言小伙伴們&#xff0c;國慶都過的開心嗎&#xff1f;國慶后的第一個工作日是不是很多小伙伴還沉浸在假期的心情中&#xff0c;沒有工作狀態呢&#xff1f;那王子今天和大家聊一聊RocketMQ的消費者是如何獲取消息的&#xff0c;通過學習知識來找回狀態吧。廢話不多說&#xf…

蘇寧 11.11:倉庫內多 AGV 協作的全局路徑規劃算法研究

本文為『InfoQ x 蘇寧 2018雙十一』技術特別策劃系列文章之一。 1. 背景 隨著物聯網和人工智能的發展&#xff0c;越來越多的任務漸漸的被機器人取代&#xff0c;機器人逐漸在發展中慢慢進入物流領域&#xff0c;“智能叉車”&#xff0c;AGV&#xff08;Automated Guided Vehi…

老板思維:工作負責人是首問責任制

工作負責人包括部門領導&#xff0c;項目經理等負責人。以項目經理為例&#xff0c;解釋這種思維。 分好幾種情況&#xff1a; &#xff08;1&#xff09;當公司&#xff08;老板&#xff0c;領導&#xff0c;甲方&#xff09;將事情交給你的時候&#xff0c;這件事情就由你負…

用python繪制玫瑰花的代碼_python也能玩出玫瑰花!程序員的表白代碼

有些情侶是異地戀&#xff0c;情人節想送朵玫瑰花給女朋友都困難。別擔心&#xff0c;用Python就好了&#xff0c;互聯網時代的戀愛神器&#xff01;接下來就讓我們一起來看看如何用Python變出玫瑰花的。 1、首先我們導入畫圖工具turtle&#xff0c;即import turtle 2、導入畫圖…

Springboot 整合 swagger

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 https://blog.csdn.net/weixin_40254498/article/details/83622098 swagger 主要是為后端服務的接口文檔&#xff0c;懶人必備&#xff0c;swagger就是一款讓你更好的書寫API文檔的框架。 其他的框架…