分享
 
 
 

内部类学习(二)

王朝other·作者佚名  2007-05-30
窄屏简体版  字體: |||超大  

许多人认为内部类的语法十分复杂,尤其是匿名内部类,这与Java所一直奉行的“简单”原则相背离的,有人甚至怀疑java中加入这么一个“特征”(feature),是不是已经开始走向“灭亡”?就像许多其它语言一样走向“灭亡”?内部类是否真的有用,有没有存在的必要?我们首先来看看内部的工作原理。

先指明一点,内部类如何工作是由编译器来负责的,与java虚拟机无关,它对这个是一无所知的。仔细留意一下上篇中编译后产生的class文件,你会发现有一个class文件的名字是Court$TimerPrinter,它的基本格式是:外部类名称$内部类名称。当碰到内部类时,编译器会自动根据内部类的代码生成一个class文件并按照上述规则命名,那么编译器到底对它做了什么呢?我们可以使用Java的反射(reflection)机制来“偷窥”它,嘿嘿。具体的代码如下所示:

* Created on 2006-09-24

*

* TODO To change the template for this generated file go to

* Window - Preferences - Java - Code Style - Code Templates

*/

package cn.edu.hust.cm.access;

import java.lang.reflect.*;

import javax.swing.*;

/**

* @author Demon

*

* TODO To change the template for this generated type comment go to

* Window - Preferences - Java - Code Style - Code Templates

*/

public class ReflectionTest {

public static void main(String[] args) {

String name="";

if(args.length>0)

name=args[0];

else

name=JOptionPane.showInputDialog("Class name (e.g. java.util.Date): ");

try{

Class c1=Class.forName(name);

Class c2=c1.getSuperclass();

System.out.print("class " + name);

if(c2!=null&&c2!=Object.class)

System.out.print(" extends " + c2.getName());

System.out.print("\n{\n");

printConstructors(c1);

System.out.println();

printMethods(c1);

System.out.println();

printFields(c1);

System.out.println("}");

}

catch(ClassNotFoundException e) { e.printStackTrace(); }

System.exit(0);

}

public static void printConstructors(Class c1){

Constructor[] constructors=c1.getDeclaredConstructors();

for(int i=0;i<constructors.length;i++){

Constructor c=constructors[i];

String name =c.getName();

System.out.print(Modifier.toString(c.getModifiers()));

System.out.print(" " + name + "(");

Class[] paramTypes = c.getParameterTypes();

for(int j=0;j<paramTypes.length;j++){

if (j > 0) System.out.print(", ");

System.out.print(paramTypes[j].getName());

}

System.out.println(");");

}

}

public static void printMethods(Class c1){

Method[] methods=c1.getDeclaredMethods();

for(int i=0;i<methods.length;i++){

Method m=methods[i];

String name=m.getName();

Class type=m.getReturnType();

System.out.print(Modifier.toString(m.getModifiers())+" "+type.getName()+" "+name+"(");

Class[] paramTypes=m.getParameterTypes();

for(int j=0;j<paramTypes.length;j++){

if(j>0) System.out.print(",");

System.out.print(paramTypes[j].getName());

}

System.out.println(");");

}

}

public static void printFields(Class c1){

Field fields[]=c1.getDeclaredFields();

for(int i=0;i<fields.length;i++){

System.out.print(Modifier.toString(fields[i].getModifiers()));

System.out.print(" ");

Class type=fields[i].getType();

System.out.print(type.getName());

System.out.println(" "+fields[i].getName()+";");

}

}

}

运行该程序,在对话框中输入cn.edu.hust.cm.test.Court$TimerPrinter,将会得到如下输出:

}

cn.edu.hust.cm.test.Court$TimerPrinter(cn.edu.hust.cm.test.Court);

public void actionPerformed(java.awt.event.ActionEvent);

final cn.edu.hust.cm.test.Court this$0;

}

如上所示,编译器自动为我们加上了一个域this$0,它指向一个外部类,另外自动给构造方法增加了一个Court型别参数,用来设置this$0的值,注意this$0是编译器自己合成的,不能直接引用。

既然编译器能够自动进行转化,为什么我们不直接自己进行转换,把TimerPrinter改写成普通的class呢?如下所示:

class Court

{

. . .

public void start()

{

ActionListener listener = new TimePrinter(this);

Timer t = new Timer(interval, listener);

t.start();

}

}

class TimePrinter implements ActionListener

{

public TimePrinter(TalkingClock clock)

{

outer = clock;

}

. . .

private TalkingClock outer;

}

问题来了,我们在实现actionPerformed方法的时候要用到访问outer.beep,但是beep是private类型的,在TimerPrinter中是不能直接访问的。这样内部类的一个优点就显示出来了:内部类能够访问其所属外部类中的私有域而其它普通的类则不行。

那么内部类是通过什么样的机制访问它所属的外部类中的私有数据的呢?联想前面讲私有域的时候,我们都是通过方法来间接访问私有域的,那么这里是不是这样的呢?我们还是对外部类Court进行一下反射,结果如下所示:

class cn.edu.hust.cm.test.Court

{

public cn.edu.hust.cm.test.Court(int, boolean);

static boolean access$0(cn.edu.hust.cm.test.Court);

public void start();

private int interval;

private boolean beep;

}

我们看到新增了一个方法access$0,它的返回值就是传递过来的Court对象的beep域,这样actionPerformed方法中的if(beep)就相当于if(access$0(outer)),内部类就是通过这种机制来访问外部类的私有数据。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有