黑马程序员技术交流社区
标题:
对eclipse代码补全功能原理的猜想及实验
[打印本页]
作者:
王海宇
时间:
2012-9-23 18:23
标题:
对eclipse代码补全功能原理的猜想及实验
虽然一直用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
复制代码
按回车,就可以看到输出结果了。例如:
请输入要加载的类的完整包名及类名(若要退出程序,请直接按回车):
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具体是不是这样工作,我也拿不准。。。欢迎大家一起讨论
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2