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