java内部测试类代码详解
我们一般使用的java内部类有4种形式:一般内部类、局部内部类、匿名内部类、静态内部类。以下是我作的一个测试,以说明各种内部类的特性。
有关内部类的特性,代码中有详细说明,如下。
/* *java内部类测试 * *InterObj反射结果: * *privateinti *privateInterObj$InterAia *publicInterObj() *publicstaticvoidmain(java.lang.String[]) *privateintgetI() *publicvoidp() *publicvoidpi() *publicvoidpp() *publicstaticvoidppp() *publicvoidpppp() *下面是编译器自动生成用于访问私有属性或方法package级别的static方法 *staticintaccess$0(InterObj) */ publicclassInterObj{ privateinti=8; privateInterAia=null; publicInterObj(){ ia=newInterA(); } privateintgetI(){ returni; } publicvoidp(){ pi(); pp(); ppp(); pppp(); } /* *在一般内部类中可以访问“外套类”中的任何级别的方法和属性。而外套类也同样可以 *访问“内部类”中的任何级别的方法和属性。因为内部类可以持有对外套类对象的引用。 *而“外套类”对于自己的需要被内部类访问的私有方法和属性,编译器都会自动生成与 *私有方法和属性相对应的“package”级别的static方法,这些方法需要用外部类对象作 *为参数,这样就可以在“package”级别的static方法中通过访问外套类中的私有方法和 *属性了。 *而对于外套类要访问内部类中的私有方法和属性,也是同样的原理,内部类在编译时, *会生成与需要被外套类访问的私有方法、属性相对应的“package”级别的static方法。 * *InterA反射结果: *privateintia *下面是内部类持有的外套类对象引用 *finalInterObjthis$0 *构造函数中用外套类对象作为参数 *InterObj$InterA(InterObj) *privatevoidpA() *下面是编译器自动生成用于访问私有属性或方法package级别的static方法 *staticvoidaccess$0(InterObj$InterA) *publicvoidpA1() * */ classInterA{ privateintia=9; privatevoidpA(){ System.out.println("thisisInterA.pA:ia="+ia+",InterObj.i="+getI()); } publicvoidpA1(){ System.out.println("thisisInterA.pA1:ia="+ia+",InterObj.i="+getI()); } } /* *局部内部类,只在方法内部可见,其它特性与一般内部类相同。 *对需要访问的局部变量,必需设置成final,因为局部内部类虽然可以持有对外套类对象的 *引用来访问外部类的属性和方法,但是却不能访问外部类方法中局部变量,所有编译器就 *在局部内部类中“拷贝”了一份需要访问的局部变量(但是对于基本类型int,float和String *等值不发生改变的类型没有拷贝)为了保证拷贝的变量值和外部方法中的变量的值所指向的 *对象是同一个对象,所以要求那些被局部类使用的局部变量应该设置成final,而不能被修 *改,这样来保证局部内中拷贝的变量和外部方法中的变量所指向的是同一个对象。变量设 *置成final只是控制变量指向的对象地址不变,而不是它指向的对象的内部属性不能改变。 * *InterB的反射结果: * *privateintib *下面是内部类持有的外套类对象引用 *finalInterObjthis$0 *下面是内部类持有的外部方法中的局部变量Test对象的引用拷贝 *privatefinalTestval$test *构造函数中用外套类对象和局部变量Test作为参数 *InterObj$1$InterB(InterObj,Test) *privatevoidpB() *下面是编译器自动生成用于访问私有属性或方法package级别的static方法 *staticvoidaccess$0(InterObj$1$InterB) */ publicvoidpi(){ finalints=5; finalTesttest=newTest(); classInterB{ privateintib=7; privatevoidpB(){ System.out.println("thisisInterB.pB:ib="+ib+ ",(Method)pi.s="+s+",Test.t="+test.getT()); } } InterBib=newInterB(); //此处改变了被局部内部类引用了的Testtest的内部状态。 //结果调用ib.pB()时,输出的就是改变后的值100 test.setT(100); ib.pB(); } /* *静态内部类,在不需要持有对“外套类对象”的引用时使用。 * *InterC反射结果:(静态内部类没有对外套类对象的引用) *privateintic *InterC() *privatevoidpC() */ staticclassInterC{ privateintic=6; privatevoidpC(){ System.out.println("thisisInterC.pC:ic="+ic); } } /* *非静态方法,可以构造静态和非静态的内部类。 *可以访问内部类中任何权限的属性和方法 */ publicvoidpp(){ InterAia=newInterA(); ia.pA(); ia.pA1(); InterCic=newInterC(); ic.pC(); //局部内部类,只在方法内部可见 //InterBib=newInterB(); } /* *静态方法,只能构造静态的内部类。 *不能构造非静态的内部类,因为静态方法中没有this来引用“外套类”的对象,来构造 *需要引用外套类对象引用的内部类对象。 */ publicstaticvoidppp(){ //InterAia=newInterA(); //但是可以如下构造: InterObjiobj=newInterObj(); InterAia=iobj.newInterA(); ia.pA(); ia.pA1(); InterCic=newInterC(); ic.pC(); //局部内部类,只在方法内部可见 //InterBib=newInterB(); } /* *匿名内部类测试 */ publicvoidpppp(){ TestInterfacetif=newTestInterface(){ publicvoidpppp(){ System.out.println("TestInterface.noName"); } } ; tif.pppp(); } /* *运行结果: *thisisInterB.pB:ib=7,(Method)pi.s=5,Test.t=100 *thisisInterA.pA:ia=9,InterObj.i=8 *thisisInterA.pA1:ia=9,InterObj.i=8 *thisisInterC.pC:ic=6 *thisisInterA.pA:ia=9,InterObj.i=8 *thisisInterA.pA1:ia=9,InterObj.i=8 *thisisInterC.pC:ic=6 *TestInterface.noName */ publicstaticvoidmain(String[]args){ InterObjio=newInterObj(); io.p(); } } /* *用于创建内部类的接口 */ interfaceTestInterface{ publicvoidpppp(); } /* *用于测试局部内部类的局部变量类 */ classTest{ privateintt=9; publicintgetT(){ returnt; } publicvoidsetT(intt1){ t=t1; } }
再分享一则实例:
publicclassInnerClass{ staticToytoy=newToy(){ Stringname="老吴"; @Override publicvoidjump() { System.out.println(name+"跳出地球"); go(); } publicvoidgo(){ System.out.println("奔跑"); } } ; /*内部类:定义在类的内部的类 *1.成员内部类: *1.1成员内部类可以直接访问外部类的属性 *1.2通过外部类名.this这种方式访问外部类的当前对象 *成员内部类实例化对象:外部类名.内部类名引用名=外部类对象.new内部类名(); *2.静态内部类 *2.1静态内部类内部不能访问外部类的成员资源,只能通过类名访问外部类的静态资源 *静态内部类实例化对象:外部类名.内部类名引用名=new外部类名.内部类名(); *3.局部内部类: *3.1也可以直接访问外部类的属性 *3.2也可以通过外部类名.this访问外部类当前对象 *3.3局部内部类只能在方法内部被访问,修饰符只能是默认的 *4.匿名内部类:在需要一个类的具体子类实例的时候,临时的生成一个类使用 *new类名(){ *重写方法; *}; *4.1匿名内部类访问外部方法的属性,该属性会被转换为常量 *4.2匿名内部类中新增的属性和方法,只能在匿名内部类内部使用 * */ publicstaticvoidmain(String[]args) { Personper=newPerson("老陈",18); Person.Computerpc=per.newComputer("外星人"); Person.Computerpc1=newPerson("简自豪",18).newComputer("外星人"); pc.runGame(); pc1.runGame(); Person.Computer1pc11=newPerson.Computer1("网吧的电脑"); pc11.runGame(); per.useComputer(); Stringstr="啦啦啦"; //str="罗库偶偶"; Computercom=newComputer(){ @Override publicvoidrunGame() { //TODOAuto-generatedmethodstub System.out.println(per.age+"岁的"+per.name+"在玩啦啦啦啦啦德玛西塔"); System.out.println(str); } } ; com.runGame(); //具体类的匿名内部类独享 /*Toytoy=newToy(){ @Override publicvoidjump() { System.out.println("跳出地球"); } };*/ toy.jump(); toy.jump(); //toy.go(); //System.out.println(toy.); } } classPerson{ Stringname; intage; staticintage1=18; staticStringname1="全职高手"; publicPerson(Stringname,intage) { super(); this.name=name; this.age=age; } publicvoidplayGame(){ System.out.println(name+"玩游戏"); } publicclassComputer{ Stringname; publicComputer(Stringname) { super(); this.name=name; } publicvoidrunGame(){ System.out.println(name+"运行游戏"); System.out.println(age+"岁的"+Person.this.name+"玩游戏"); } } publicstaticclassComputer1{ Stringname; publicComputer1(Stringname) { super(); this.name=name; } publicvoidrunGame(){ System.out.println(name+"运行游戏"); System.out.println(Person.age1+"的"+Person.name1+"在玩游戏"); } } publicvoiduseComputer(){ classComputer{ Stringname; publicComputer(Stringname) { super(); this.name=name; } publicvoidrunGame(){ System.out.println(name+"运行游戏"); System.out.println(Person.this.age+"的"+Person.this.name+"正在玩游戏"); } } Computercom=newComputer("笔记本"); com.runGame(); } } publicinterfaceComputer{ voidrunGame(); } publicclassToy{ publicvoidjump(){ System.out.println("玩具跳一下"); } }
总结
以上就是本文关于java内部测试类代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!