顶点小说
会员书架
首页 >玄幻奇幻 >该书审核已经通过fxl > 这里我要谈点题外话

这里我要谈点题外话(2 / 2)

上一页 章节目录 加入书签 下一章

class类十分特殊。它和一般类一样继承自object,其实体用以表达java程序运行时的classes和interfaces,也用来表达enum、array、primitivejavatypes(boolean,byte,char,short,int,long,float,double)以及关键词void。当一个class被加载,或当加载器(classloader)的defineclass()被jvm调用,jvm便自动产生一个class对象。如果您想借由“修改java标准库源码”来观察class对象的实际生成时机(例如在class的constructor内添加一个println()),这样是行不通的!因为class并没有publicconstructor。

class是reflection故事起源。针对任何您想探勘的类,唯有先为它产生一个class对象,接下来才能经由后者唤起为数十多个的reflectionapis。这些apis将在稍后的探险活动中一一亮相。找出class参用(导入)的所有classes

没有直接可用的reflectionapi可以为我们找出某个class参用的所有其它classes。要获得这项信息,必须做苦工,一步一脚印逐一记录。我们必须观察所有fields的类型、所有methods(包括constructors)的参数类型和回返类型,剔除重复,留下唯一。这正是为什么图5-tance()。图7首先准备一个class[]做为ctor的参数类型(本例指定为一个double和一个int),然后以此为自变量调用getconstructor(),获得一个专属ctor。接下来再准备一个object[]做为ctor实参值(本例指定3.14159和125),调用上述专属ctor的newinstance()。动态生成“classobject对应之class”的对象实体;自变量以object[]表示。

运行时调用methods

这个动作和上述调用“带参数之ctor”相当类似。首先准备一个class[]做为ctor的参数类型(本例指定其中一个是string,另一个是hashtable),然后以此为自变量调用getmethod(),获得特定的methodobject。接下来准备一个object[]放置自变量,然后调用上述所得之特定methodobject的invoke(),如图8。知道为什么索取methodobject时不需指定回返类型吗?因为methodoverloading机制要求signature(署名式)必须唯一,而回返类型并非signature的一个成份。换句话说,只要指定了method名称和参数列,就一定指出了一个独一无二的method。先前我曾提到,原本想借由“改动java标准库源码”来测知classobject的生成,但由于其ctor原始设计为private,也就是说不可能透过这个管道生成classobject(而是由classloader负责生成),因此“在ctor中打印出某种信息”的企图也就失去了意义。

这里我要谈点题外话:如何修改java标准库源码并让它反应到我们的应用程序来。假设我想修改java.lang.class,让它在某些情况下打印某种信息。首先必须找出标准源码!当你下载jdk套件并安装妥当,你会发现jdk150\\src\\java\\lang目录(见图10)之中有class.java,这就是我们此次行动的标准源码。备份后加以修改,编译获得class.class。接下来准备将.class搬移到jdk150\\jre\\lib\\endorsed(见图10)。

这是一个十分特别的目录,classloader将优先从该处读取内含classes的.jar文件——成功的条件是.jar内的classes压缩路径必须和java标准库的路径完全相同。为此,我们可以将刚才做出的class.class先搬到一个为此目的而刻意做出来的\\java\\lang目录中,压缩为foo.zip(任意命名,唯需夹带路径java\\lang),再将这个foo.zip搬到jdk150\\jre\\lib\\endorsed并改名为foo.jar。此后你的应用程序便会优先用上这里的java.lang.class。整个过程可写成一个批处理文件(batchfile),如图11,在dosbox中使用。

点击切换 [繁体版]    [简体版]
上一页 章节目录 加入书签 下一章