java內(nèi)部類原理與用法詳解
本文實(shí)例講述了java內(nèi)部類原理與用法。分享給大家供大家參考,具體如下:
概念
內(nèi)部類:可以包含在另外一個(gè)類中的類
外部類:包含內(nèi)部類的類
每個(gè)內(nèi)部類都會(huì)被編譯為一個(gè)獨(dú)立的類,生成一個(gè)獨(dú)立的字節(jié)碼文件。
內(nèi)部類可以方便地訪問外部類的私有變量,內(nèi)部類也可以聲明為private從而實(shí)現(xiàn)對外完全隱藏。
分類
java中的四種內(nèi)部類(根據(jù)定義的位置和方式劃分)
- -靜態(tài)內(nèi)部類
- -成員內(nèi)部類
- -方法內(nèi)部類
- -匿名內(nèi)部類
分類介紹
-靜態(tài)內(nèi)部類
特征:在類的內(nèi)部中存在另一個(gè)類,且該類被static修飾
使用范圍:在外部類內(nèi),可以直接使用內(nèi)部類,在外部類范圍以外使用外部類名.靜態(tài)內(nèi)部類名
的方式使用內(nèi)部類
public class StaticOuter { private static int shared = 100; public static class StaticInner{ public void staticInnerMethod() { System.out.println("Static Inner Method" + shared); } } StaticInner si1 = new StaticInner(); public void test() { StaticInner si = new StaticInner(); si.staticInnerMethod(); } public static void main(String[] args) { StaticOuter so = new StaticOuter(); so.test(); //在外部類范圍內(nèi) StaticInner si1 = new StaticInner(); si1.staticInnerMethod(); //合法 StaticOuter.StaticInner si2 = new StaticOuter.StaticInner(); si2.staticInnerMethod(); } } //在外部類范圍外 class Test{ StaticOuter.StaticInner si2 = new StaticOuter.StaticInner(); }
訪問范圍
- 靜態(tài)內(nèi)部類只能訪問外部類中的static變量和方法。
- 靜態(tài)內(nèi)部類也可以訪問外部類中的private變量。
- 靜態(tài)內(nèi)部類中可以定義靜態(tài)變量和靜態(tài)方法。
-成員內(nèi)部類
語法:成員內(nèi)部類作為外部類的一個(gè)成員存在
使用方法:
如何新建一個(gè)內(nèi)部類的實(shí)例:不能直接使用外部類.內(nèi)部類的方式,每個(gè)成員內(nèi)部類對象對應(yīng)一個(gè)外部類實(shí)例,因此需要先創(chuàng)建一個(gè)外部類實(shí)例,然后才能生成內(nèi)部類的實(shí)例(如下面代碼)
訪問范圍:
成員內(nèi)部類可以訪問外部類中的靜態(tài)變量和方法,也可以訪問實(shí)例變量和方法。但是書寫格式有兩種:
(1)直接訪問;
(2)外部類.this.xxx
,主要針對外部類和內(nèi)部類的出現(xiàn)變量重名或者方法重名的情況。
成員內(nèi)部類也可以訪問外部類的私有變量
成員內(nèi)部類中不可以定義靜態(tài)變量和靜態(tài)方法(final變量例外,它等同于常量),在后面的方法內(nèi)部類和匿名內(nèi)部類中也是不能存在靜態(tài)的變量和方法的,這是因?yàn)殪o態(tài)變量和靜態(tài)方法作為類型的屬性和方法,一般是獨(dú)立使用的,而成員內(nèi)部類和一個(gè)對一個(gè)的外部類實(shí)例關(guān)聯(lián),一般不會(huì)獨(dú)立使用,所以這樣的使用意義不大。(這算是一種規(guī)定吧)。
public class OriginalClass { private static int t1 = 100; private int t2 = 200; class OriginalInner{ public void test() { /* * 不合法的表示,在成員內(nèi)部類中不可以定義靜態(tài)的變量和方法 public static int inner = 100; public static void print() { } */ //合法的final變量 public static final int inner1 = 300; System.out.println("OriginalInner:"+ t1);//直接訪問外部類靜態(tài)變量 System.out.println("OriginalInner:"+ t2);//直接訪問外部類成員變量 action();//直接訪問外部類方法 System.out.println("OriginalInner:"+ OriginalClass.this.t1);// System.out.println("OriginalInner:"+ OriginalClass.this.t2); OriginalClass.this.action(); } } public void action() { System.out.println("originalinner action"); } public static void main(String[] args) { //new一個(gè)內(nèi)部類 OriginalClass oc = new OriginalClass(); OriginalInner oi = oc.new OriginalInner(); oi.test(); } }
-方法內(nèi)部類
語法:存在于方法體內(nèi)部的類
使用范圍:方法內(nèi)部類只能在定義的方法內(nèi)被使用
訪問范圍:
如果包含內(nèi)部類的方法是實(shí)例方法,那么可以訪問外部類的靜態(tài)變量和方法,也可以訪問實(shí)例變量和方法;
如果包含內(nèi)部類的方法是靜態(tài)方法,那么只能訪問外部類的靜態(tài)變量和方法。
方法內(nèi)部類還可以直接訪問方法的參數(shù)和方法中的局部變量,但是這些變量必須聲明為final。為什么需要聲明為final呢?這是因?yàn)榉椒▋?nèi)部類操作的并不是外部的變量,而是它自己的實(shí)例變量,只是這些變量的值和外部一樣,對這些變量賦值,并不會(huì)改變外部的值,為避免混淆,所以干脆強(qiáng)制規(guī)定必須聲明為final。
我們知道被final修飾的基本類型變量的值是不能被修改的,被final修飾的數(shù)組或者引用類型變量的引用是不能修改的,即只能指向一個(gè)對象或者是數(shù)組,但是我們可以修改對象中的成員變量值或者是數(shù)組中元素的值。
其實(shí)使用final來修飾參數(shù)以及局部變量的目的還是保證方法內(nèi)部類外面的元素不會(huì)在方法內(nèi)部類中被修改,相當(dāng)于限制一個(gè)作用域的功能,保證方法內(nèi)部類內(nèi)部的的修改不會(huì)影響方法內(nèi)部類外面的同名變量值。
public class FunctionOuter { private static int s= 100; private int s1 = 20; public void print(final int param) { final int in = 300; class FunctionInner{ public void innertest() { System.out.println("FunctionInner:s="+s); System.out.println("FunctionInner:s1="+s1); System.out.println("FunctionInner:in"+ in); test(); } } FunctionInner fi = new FunctionInner(); fi.innertest(); System.out.println("print:in"+in); } public void test() { System.out.println("FunctionOuter:"+s); } public static void main(String[] args) { FunctionOuter fo = new FunctionOuter(); fo.print(900); } }
-匿名內(nèi)部類
語法:匿名內(nèi)部類沒有單獨(dú)的類定義,它在創(chuàng)建對象的同時(shí)定義類
new 父類(參數(shù)列表){ //匿名內(nèi)部類實(shí)現(xiàn)部分 }
new 父接口(){ //匿名內(nèi)部類實(shí)現(xiàn)部分 }
匿名內(nèi)部類只能使用一次,用來創(chuàng)建一個(gè)對象。沒有名字,沒有構(gòu)造方法,但是可以根據(jù)參數(shù)列表,調(diào)用對應(yīng)的父類構(gòu)造方法。
在匿名內(nèi)部類中可以定義實(shí)例變量和方法,以及初始化代碼塊,初始化代碼塊可以起到構(gòu)造方法的作用,只是構(gòu)造方法可以有多個(gè),但是初始化代碼塊只能有一塊,因?yàn)闆]有構(gòu)造方法,它自己無法接受參數(shù),如果必須要參數(shù),則應(yīng)該是用其他內(nèi)部類。
匿名內(nèi)部類可以訪問外部類的所有變量和方法,可以訪問方法中的final參數(shù)和局部變量
更多java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
基于Java堆內(nèi)存的10個(gè)要點(diǎn)的總結(jié)分析
本篇文章是對Java堆內(nèi)存的10個(gè)要點(diǎn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Spring Boot 集成Shiro的多realm實(shí)現(xiàn)以及shiro基本入門教程
這篇文章主要介紹了Spring Boot 集成Shiro的多realm實(shí)現(xiàn)以及shiro基本入門,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Java實(shí)現(xiàn)獲取小程序帶參二維碼并保存到本地
這篇文章主要介紹了Java實(shí)現(xiàn)獲取小程序帶參二維碼并保存到本地,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10JAVA JDK8 List分組獲取第一個(gè)元素的方法
今天小編就為大家分享一篇關(guān)于JAVA JDK8 List分組獲取第一個(gè)元素的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12springCloud gateWay 統(tǒng)一鑒權(quán)的實(shí)現(xiàn)代碼
這篇文章主要介紹了springCloud gateWay 統(tǒng)一鑒權(quán)的實(shí)現(xiàn)代碼,統(tǒng)一鑒權(quán)包括鑒權(quán)邏輯和代碼實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02基于SpringBoot和Vue寫一個(gè)2048小游戲
創(chuàng)建一個(gè)基于 Java Spring Boot 后端和 Vue 前端的 2048 游戲,可以按照以下步驟進(jìn)行,這個(gè)項(xiàng)目將包括后端(用來處理游戲邏輯)和前端(用來顯示游戲界面和與用戶交互),感興趣的小伙伴可以參考本文自己動(dòng)手嘗試一下2024-08-08Spring Cloud Gateway網(wǎng)關(guān)XSS過濾方式
這篇文章主要介紹了Spring Cloud Gateway網(wǎng)關(guān)XSS過濾方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10