虽然一直用eclipse,但是从没想过它的工作原理是什么,今天在复习反射的时候,就联想到,eclipse的代码补全功能是否就是通过反射要提示的类来实现的呢?然后就自己写了一个简单的程序,来实验一下,代码如下- import java.io.BufferedReader;
- import java.io.File;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.lang.reflect.Modifier;
- public class ReflectTest {
- @SuppressWarnings("rawtypes")
- public static void main(String[] args) throws IOException,
- ClassNotFoundException {
- while (true) {
- System.out.println("请输入要加载的类的完整包名及类名(若要退出程序,请直接按回车):");
- // 获取用户的输入。例:org.dom4j.Branch
- String name = new BufferedReader(new InputStreamReader(System.in))
- .readLine();
- System.out.println();
- // 检查用户是否想继续操作
- if ("".equals(name)) {
- System.out.println("你没有输入任何信息,程序将退出");
- return;
- }
- // 根据用户输入,生成格式化的class文件路径
- String filePath = name.replaceAll("\\.", "/") + ".class";
- File file = new File(filePath);
- // 检查用户输入的文件是否存在
- if (!file.exists() || !file.isFile()) {
- System.out.println("你输入的文件路径及名称无效,请检查目录 "
- + file.getParentFile().getAbsolutePath() + " 下是否有 "
- + file.getName() + " 这个文件!!\n");
- continue;
- }
- System.out.println("···现在开始分析位于" + file.getAbsolutePath()
- + "的class文件···\n");
- // 加载用户希望分析的类
- Class clazz = Class.forName(name);
- // 获取要分析的类的所有公开字段
- Field[] fields = clazz.getFields();
- for (Field field : fields) {
- System.out.println("找到字段:"
- // 得到字段的修饰符
- + Modifier.toString(field.getModifiers()) + " "
- // 得到字段的名称
- + field.getName());
- }
- System.out.println();
- // 获取要分析的类的所有公开方法
- Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- System.out.print("找到方法:"
- // 得到方法的修饰符
- + Modifier.toString(method.getModifiers()) + " "
- // 得到方法的名称
- + method.getName() + "(");
- int i = 1;
- // 得到方法中所有的参数类型字节码
- Class[] argTypes = method.getParameterTypes();
- for (Class clazz2 : argTypes) {
- // 获取参数类型名
- String argName = clazz2.getName();
- // 格式化参数类型名
- argName = argName.substring(argName.lastIndexOf(".") + 1);
- System.out.print(argName + " " + "arg" + i);
- if (i < argTypes.length)
- System.out.print(", ");
- i++;
- }
- System.out.println(")");
- }
- System.out.println("\n······文件分析完毕······\n");
- }
- }
- }
复制代码 假设ReflectTest.java位于D盘,要分析的文件位于D:\org\dom4j\io\XMLWriter.class。(org.dom4j.io是完整包名)
编译完毕后,执行java ReflectTest,然后输入按回车,就可以看到输出结果了。例如:- 请输入要加载的类的完整包名及类名(若要退出程序,请直接按回车):
- org.dom4j.io.XMLWriter
- ···现在开始分析位于D:\\org\dom4j\io\XMLWriter.class的class文件···
- 找到方法:public startDTD(String arg1, String arg2, String arg3)
- 找到方法:public endDTD()
- 找到方法:public startEntity(String arg1)
- 找到方法:public endEntity(String arg1)
- 找到方法:public startCDATA()
- 找到方法:public endCDATA()
- 找到方法:public resolveEntityRefs()
- 找到方法:public setWriter(Writer arg1)
- 找到方法:public setOutputStream(OutputStream arg1)
- 找到方法:public isEscapeText()
- 找到方法:public setEscapeText(boolean arg1)
- 找到方法:public setIndentLevel(int arg1)
- 找到方法:public getMaximumAllowedCharacter()
- 找到方法:public setMaximumAllowedCharacter(int arg1)
- 找到方法:public writeOpen(Element arg1)
- 找到方法:public writeClose(Element arg1)
- 找到方法:public setLexicalHandler(LexicalHandler arg1)
- 找到方法:public getLexicalHandler()
- 找到方法:public setResolveEntityRefs(boolean arg1)
- 找到方法:public println()
- 找到方法:public setProperty(String arg1, Object arg2)
- 找到方法:public getProperty(String arg1)
- 找到方法:public write(String arg1)
- 找到方法:public write(ProcessingInstruction arg1)
- 找到方法:public write(Attribute arg1)
- 找到方法:public write(Document arg1)
- 找到方法:public write(Node arg1)
- 找到方法:public write(Element arg1)
- 找到方法:public write(CDATA arg1)
- 找到方法:public write(Comment arg1)
- 找到方法:public write(DocumentType arg1)
- 找到方法:public write(Entity arg1)
- 找到方法:public write(Namespace arg1)
- 找到方法:public write(Object arg1)
- 找到方法:public write(Text arg1)
- 找到方法:public close()
- 找到方法:public flush()
- 找到方法:public parse(InputSource arg1)
- 找到方法:public comment([C arg1, int arg2, int arg3)
- 找到方法:public characters([C arg1, int arg2, int arg3)
- 找到方法:public endDocument()
- 找到方法:public endElement(String arg1, String arg2, String arg3)
- 找到方法:public endPrefixMapping(String arg1)
- 找到方法:public ignorableWhitespace([C arg1, int arg2, int arg3)
- 找到方法:public notationDecl(String arg1, String arg2, String arg3)
- 找到方法:public processingInstruction(String arg1, String arg2)
- 找到方法:public setDocumentLocator(Locator arg1)
- 找到方法:public startDocument()
- 找到方法:public startElement(String arg1, String arg2, String arg3, Attributes
- arg4)
- 找到方法:public startPrefixMapping(String arg1, String arg2)
- 找到方法:public unparsedEntityDecl(String arg1, String arg2, String arg3, Strin
- g arg4)
- 找到方法:public getErrorHandler()
- 找到方法:public getEntityResolver()
- 找到方法:public setContentHandler(ContentHandler arg1)
- 找到方法:public getDTDHandler()
- 找到方法:public setDTDHandler(DTDHandler arg1)
- 找到方法:public getParent()
- 找到方法:public setParent(XMLReader arg1)
- 找到方法:public fatalError(SAXParseException arg1)
- 找到方法:public error(SAXParseException arg1)
- 找到方法:public parse(String arg1)
- 找到方法:public getContentHandler()
- 找到方法:public warning(SAXParseException arg1)
- 找到方法:public getFeature(String arg1)
- 找到方法:public resolveEntity(String arg1, String arg2)
- 找到方法:public setFeature(String arg1, boolean arg2)
- 找到方法:public setEntityResolver(EntityResolver arg1)
- 找到方法:public setErrorHandler(ErrorHandler arg1)
- 找到方法:public skippedEntity(String arg1)
- 找到方法:public final wait()
- 找到方法:public final wait(long arg1, int arg2)
- 找到方法:public final native wait(long arg1)
- 找到方法:public native hashCode()
- 找到方法:public final native getClass()
- 找到方法:public equals(Object arg1)
- 找到方法:public toString()
- 找到方法:public final native notify()
- 找到方法:public final native notifyAll()
- ······文件分析完毕······
复制代码 找的例子class文件里面正好没有公开字段,所以只找出了公开的方法。。
从上面的内容可以分析,在使用eclipse的代码补全提示的时候,eclipse应该也是采用反射的方法(这也说明在我们编写代码的时候,eclipse已经将我们用到的各种类的class文件加载到了内存中),获取要使用的类的方法以及字段,然后将它们进行包装以后,就将其显示在了提示列表中。当然这只是我的猜想,eclipse具体是不是这样工作,我也拿不准。。。欢迎大家一起讨论
|