java內(nèi)部測(cè)試類(lèi)代碼詳解
我們一般使用的java內(nèi)部類(lèi)有4種形式:一般內(nèi)部類(lèi)、局部?jī)?nèi)部類(lèi)、匿名內(nèi)部類(lèi)、靜態(tài)內(nèi)部類(lèi)。以下是我作的一個(gè)測(cè)試,以說(shuō)明各種內(nèi)部類(lèi)的特性。
有關(guān)內(nèi)部類(lèi)的特性,代碼中有詳細(xì)說(shuō)明,如下。
/* * java內(nèi)部類(lèi)測(cè)試 * * InterObj反射結(jié)果: * * private int i * private InterObj$InterA ia * public InterObj() * public static void main(java.lang.String[]) * private int getI() * public void p() * public void pi() * public void pp() * public static void ppp() * public void pppp() * 下面是編譯器自動(dòng)生成用于訪問(wèn)私有屬性或方法package級(jí)別的static方法 * static int access$0(InterObj) */ public class InterObj { private int i=8; private InterA ia=null; public InterObj(){ ia=new InterA(); } private int getI(){ return i; } public void p(){ pi(); pp(); ppp(); pppp(); } /* * 在一般內(nèi)部類(lèi)中可以訪問(wèn)“外套類(lèi)”中的任何級(jí)別的方法和屬性。而外套類(lèi)也同樣可以 * 訪問(wèn)“內(nèi)部類(lèi)”中的任何級(jí)別的方法和屬性。因?yàn)閮?nèi)部類(lèi)可以持有對(duì)外套類(lèi)對(duì)象的引用。 * 而“外套類(lèi)”對(duì)于自己的需要被內(nèi)部類(lèi)訪問(wèn)的私有方法和屬性,編譯器都會(huì)自動(dòng)生成與 * 私有方法和屬性相對(duì)應(yīng)的“package”級(jí)別的static方法,這些方法需要用外部類(lèi)對(duì)象作 * 為參數(shù),這樣就可以在“package”級(jí)別的static方法中通過(guò)訪問(wèn)外套類(lèi)中的私有方法和 * 屬性了。 * 而對(duì)于外套類(lèi)要訪問(wèn)內(nèi)部類(lèi)中的私有方法和屬性,也是同樣的原理,內(nèi)部類(lèi)在編譯時(shí), * 會(huì)生成與需要被外套類(lèi)訪問(wèn)的私有方法、屬性相對(duì)應(yīng)的“package”級(jí)別的static方法。 * * InterA反射結(jié)果: * private int ia * 下面是內(nèi)部類(lèi)持有的外套類(lèi)對(duì)象引用 * final InterObj this$0 * 構(gòu)造函數(shù)中用外套類(lèi)對(duì)象作為參數(shù) * InterObj$InterA(InterObj) * private void pA() * 下面是編譯器自動(dòng)生成用于訪問(wèn)私有屬性或方法package級(jí)別的static方法 * static void access$0(InterObj$InterA) * public void pA1() * */ class InterA{ private int ia=9; private void pA(){ System.out.println("this is InterA.pA: ia="+ia+",InterObj.i="+getI()); } public void pA1(){ System.out.println("this is InterA.pA1: ia="+ia+",InterObj.i="+getI()); } } /* * 局部?jī)?nèi)部類(lèi),只在方法內(nèi)部可見(jiàn),其它特性與一般內(nèi)部類(lèi)相同。 * 對(duì)需要訪問(wèn)的局部變量,必需設(shè)置成final,因?yàn)榫植績(jī)?nèi)部類(lèi)雖然可以持有對(duì)外套類(lèi)對(duì)象的 * 引用來(lái)訪問(wèn)外部類(lèi)的屬性和方法,但是卻不能訪問(wèn)外部類(lèi)方法中局部變量,所有編譯器就 * 在局部?jī)?nèi)部類(lèi)中“拷貝”了一份需要訪問(wèn)的局部變量(但是對(duì)于基本類(lèi)型int,float和String * 等值不發(fā)生改變的類(lèi)型沒(méi)有拷貝)為了保證拷貝的變量值和外部方法中的變量的值所指向的 * 對(duì)象是同一 個(gè)對(duì)象,所以要求那些被局部類(lèi)使用的局部變量應(yīng)該設(shè)置成final,而不能被修 * 改,這樣來(lái)保證局部?jī)?nèi)中拷貝的變量和外部方法中的變量所指向的是同一個(gè)對(duì)象。變量設(shè) * 置成final只是控制變量指向的對(duì)象地址不變,而不是它指向的對(duì)象的內(nèi)部屬性不能改變。 * * InterB的反射結(jié)果: * * private int ib * 下面是內(nèi)部類(lèi)持有的外套類(lèi)對(duì)象引用 * final InterObj this$0 * 下面是內(nèi)部類(lèi)持有的外部方法中的局部變量Test對(duì)象的引用拷貝 * private final Test val$test * 構(gòu)造函數(shù)中用外套類(lèi)對(duì)象和局部變量Test作為參數(shù) * InterObj$1$InterB(InterObj,Test) * private void pB() * 下面是編譯器自動(dòng)生成用于訪問(wèn)私有屬性或方法package級(jí)別的static方法 * static void access$0(InterObj$1$InterB) */ public void pi(){ final int s=5; final Test test=new Test(); class InterB{ private int ib=7; private void pB(){ System.out.println("this is InterB.pB: ib="+ib+ ",(Method)pi.s="+s+",Test.t="+test.getT()); } } InterB ib=new InterB(); //此處改變了被局部?jī)?nèi)部類(lèi)引用了的Test test的內(nèi)部狀態(tài)。 //結(jié)果調(diào)用ib.pB()時(shí),輸出的就是改變后的值100 test.setT(100); ib.pB(); } /* * 靜態(tài)內(nèi)部類(lèi),在不需要持有對(duì)“外套類(lèi)對(duì)象”的引用時(shí)使用。 * * InterC反射結(jié)果:(靜態(tài)內(nèi)部類(lèi)沒(méi)有對(duì)外套類(lèi)對(duì)象的引用) * private int ic * InterC() * private void pC() */ static class InterC{ private int ic=6; private void pC(){ System.out.println("this is InterC.pC: ic="+ic); } } /* * 非靜態(tài)方法,可以構(gòu)造靜態(tài)和非靜態(tài)的內(nèi)部類(lèi)。 * 可以訪問(wèn)內(nèi)部類(lèi)中任何權(quán)限的屬性和方法 */ public void pp(){ InterA ia=new InterA(); ia.pA(); ia.pA1(); InterC ic=new InterC(); ic.pC(); //局部?jī)?nèi)部類(lèi),只在方法內(nèi)部可見(jiàn) //InterB ib=new InterB(); } /* * 靜態(tài)方法,只能構(gòu)造靜態(tài)的內(nèi)部類(lèi)。 * 不能構(gòu)造非靜態(tài)的內(nèi)部類(lèi),因?yàn)殪o態(tài)方法中沒(méi)有this來(lái)引用“外套類(lèi)”的對(duì)象,來(lái)構(gòu)造 * 需要引用外套類(lèi)對(duì)象引用的內(nèi)部類(lèi)對(duì)象。 */ public static void ppp(){ //InterA ia=new InterA(); //但是可以如下構(gòu)造: InterObj iobj=new InterObj(); InterA ia=iobj.new InterA(); ia.pA(); ia.pA1(); InterC ic=new InterC(); ic.pC(); //局部?jī)?nèi)部類(lèi),只在方法內(nèi)部可見(jiàn) //InterB ib=new InterB(); } /* * 匿名內(nèi)部類(lèi)測(cè)試 */ public void pppp(){ TestInterface tif=new TestInterface(){ public void pppp() { System.out.println("TestInterface.noName"); } } ; tif.pppp(); } /* * 運(yùn)行結(jié)果: * this is InterB.pB: ib=7,(Method)pi.s=5,Test.t=100 * this is InterA.pA: ia=9,InterObj.i=8 * this is InterA.pA1: ia=9,InterObj.i=8 * this is InterC.pC: ic=6 * this is InterA.pA: ia=9,InterObj.i=8 * this is InterA.pA1: ia=9,InterObj.i=8 * this is InterC.pC: ic=6 * TestInterface.noName */ public static void main(String[] args) { InterObj io=new InterObj(); io.p(); } } /* * 用于創(chuàng)建內(nèi)部類(lèi)的接口 */ interface TestInterface{ public void pppp(); } /* * 用于測(cè)試局部?jī)?nèi)部類(lèi)的局部變量類(lèi) */ class Test{ private int t=9; public int getT(){ return t; } public void setT(int t1){ t=t1; } }
再分享一則實(shí)例:
public class InnerClass { static Toy toy = new Toy(){ String name = "老吳"; @Override public void jump() { System.out.println(name+"跳出地球"); go(); } public void go(){ System.out.println("奔跑"); } } ; /*內(nèi)部類(lèi):定義在類(lèi)的內(nèi)部的類(lèi) *1.成員內(nèi)部類(lèi): *1.1成員內(nèi)部類(lèi)可以直接訪問(wèn)外部類(lèi)的屬性 *1.2通過(guò) 外部類(lèi)名.this 這種方式訪問(wèn)外部類(lèi)的當(dāng)前對(duì)象 *成員內(nèi)部類(lèi)實(shí)例化對(duì)象: 外部類(lèi)名.內(nèi)部類(lèi)名 引用名 = 外部類(lèi)對(duì)象.new 內(nèi)部類(lèi)名(); *2.靜態(tài)內(nèi)部類(lèi) *2.1靜態(tài)內(nèi)部類(lèi)內(nèi)部不能訪問(wèn)外部類(lèi)的成員資源,只能通過(guò)類(lèi)名訪問(wèn)外部類(lèi)的靜態(tài)資源 *靜態(tài)內(nèi)部類(lèi)實(shí)例化對(duì)象: 外部類(lèi)名.內(nèi)部類(lèi)名 引用名 = new 外部類(lèi)名.內(nèi)部類(lèi)名(); *3.局部?jī)?nèi)部類(lèi): *3.1也可以直接訪問(wèn)外部類(lèi)的屬性 *3.2也可以通過(guò) 外部類(lèi)名.this 訪問(wèn)外部類(lèi)當(dāng)前對(duì)象 *3.3局部?jī)?nèi)部類(lèi)只能在方法內(nèi)部被訪問(wèn),修飾符只能是默認(rèn)的 *4.匿名內(nèi)部類(lèi):在需要一個(gè)類(lèi)的具體子類(lèi)實(shí)例的時(shí)候,臨時(shí)的生成一個(gè)類(lèi)使用 *new 類(lèi)名(){ * 重寫(xiě)方法; *}; *4.1匿名內(nèi)部類(lèi)訪問(wèn)外部方法的屬性,該屬性會(huì)被轉(zhuǎn)換為常量 *4.2匿名內(nèi)部類(lèi)中新增的屬性和方法,只能在匿名內(nèi)部類(lèi)內(nèi)部使用 * */ public static void main(String[] args) { Person per = new Person("老陳",18); Person.Computer pc = per.new Computer("外星人"); Person.Computer pc1 = new Person("簡(jiǎn)自豪",18).new Computer("外星人"); pc.runGame(); pc1.runGame(); Person.Computer1 pc11 = new Person.Computer1("網(wǎng)吧的電腦"); pc11.runGame(); per.useComputer(); String str = "啦啦啦"; //str = "羅庫(kù)偶偶"; Computer com = new Computer(){ @Override public void runGame() { // TODO Auto-generated method stub System.out.println(per.age+"歲的"+per.name+"在玩啦啦啦啦啦德瑪西塔"); System.out.println(str); } } ; com.runGame(); //具體類(lèi)的匿名內(nèi)部類(lèi)獨(dú)享 /*Toy toy = new Toy(){ @Override public void jump() { System.out.println("跳出地球"); } };*/ toy.jump(); toy.jump(); //toy.go(); //System.out.println(toy.); } } class Person { String name; int age; static int age1 = 18; static String name1 = "全職高手"; public Person(String name,int age) { super(); this.name = name; this.age = age; } public void playGame(){ System.out.println(name+"玩游戲"); } public class Computer{ String name; public Computer(String name) { super(); this.name = name; } public void runGame(){ System.out.println(name+"運(yùn)行游戲"); System.out.println(age+"歲的"+Person.this.name+"玩游戲"); } } public static class Computer1{ String name; public Computer1(String name) { super(); this.name = name; } public void runGame(){ System.out.println(name+"運(yùn)行游戲"); System.out.println(Person.age1+"的"+Person.name1+"在玩游戲"); } } public void useComputer(){ class Computer{ String name; public Computer(String name) { super(); this.name = name; } public void runGame(){ System.out.println(name+"運(yùn)行游戲"); System.out.println(Person.this.age+"的"+Person.this.name+"正在玩游戲"); } } Computer com = new Computer("筆記本"); com.runGame(); } } public interface Computer { void runGame(); } public class Toy { public void jump(){ System.out.println("玩具跳一下"); } }
總結(jié)
以上就是本文關(guān)于java內(nèi)部測(cè)試類(lèi)代碼詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
相關(guān)文章
springAOP的三種實(shí)現(xiàn)方式示例代碼
這篇文章主要介紹了springAOP的三種實(shí)現(xiàn)方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Java之maven打完jar包之后將jar包放到指定位置匯總
這篇文章主要介紹了Java之maven打完jar包之后將jar包放到指定位置匯總,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04Spring Security 表單登錄功能的實(shí)現(xiàn)方法
這篇文章主要介紹了Spring Security 表單登錄,本文將構(gòu)建在之前簡(jiǎn)單的 Spring MVC示例 之上,因?yàn)檫@是設(shè)置Web應(yīng)用程序和登錄機(jī)制的必不可少的。需要的朋友可以參考下2019-06-06Java如何優(yōu)雅地避免空指針異常(NullPointerException)
這篇文章主要給大家介紹了關(guān)于Java如何優(yōu)雅地避免空指針異常(NullPointerException)的相關(guān)資料,空指針異常(NullPointerException)是一種常見(jiàn)的運(yùn)行時(shí)異常,它在Java編程中經(jīng)常出現(xiàn),需要的朋友可以參考下2024-03-03springboot快速整合Mybatis組件的方法(推薦)
Spring Boot是由Pivotal團(tuán)隊(duì)提供的全新框架,其設(shè)計(jì)目的是用來(lái)簡(jiǎn)化新Spring應(yīng)用的初始搭建以及開(kāi)發(fā)過(guò)程。這篇文章主要介紹了springboot快速整合Mybatis組件的方法,需要的朋友可以參考下2019-11-11idea注解參數(shù)換行時(shí)間日期格式設(shè)置方法
這篇文章主要介紹了idea注解參數(shù)換行時(shí)間日期格式設(shè)置方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05java通過(guò)HTTP接收json詳細(xì)實(shí)例代碼
Java作為一門(mén)廣泛使用的編程語(yǔ)言,很多開(kāi)發(fā)人員會(huì)用它來(lái)進(jìn)行http請(qǐng)求,獲取json數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于java通過(guò)HTTP接收json的相關(guān)資料,需要的朋友可以參考下2023-11-11