从纯文本检测Java类名

从纯文本检测Java类名,java,Java,假设您有以下Java代码: public class Test { public Test() { string name = "Robot"; Robot aRobot = new Robot(); List<String> aList = new List<String>(); } } 公共类测试{ 公开考试(){ string name=“Robot”; Robot aRobot=新机器人(); 列表

假设您有以下Java代码:

public class Test {
    public Test() {
        string name = "Robot";
        Robot aRobot = new Robot();
        List<String> aList = new List<String>();
    }
}
公共类测试{
公开考试(){
string name=“Robot”;
Robot aRobot=新机器人();
列表列表=新列表();
}
}
如何检测
Test
string
List
Robot
是类名称及其在文本文件中的位置?

您可以使用refection API在java文件中查找字段的类型。
You can use Refelction API for finding the type of the field in your java file.

import java.lang.reflect.Field;
import java.util.List;

public class FieldSpy<T> {
    public boolean[][] b = {{ false, false }, { true, true } };
    public String name  = "Alice";
    public List<Integer> list;
    public T val;

    public static void main(String... args) {
    try {
        Class<?> c = Class.forName(args[0]);
        Field f = c.getField(args[1]);
        System.out.format("Type: %s%n", f.getType());
        System.out.format("GenericType: %s%n", f.getGenericType());

        // production code should handle these exceptions more gracefully
    } catch (ClassNotFoundException x) {
        x.printStackTrace();
    } catch (NoSuchFieldException x) {
        x.printStackTrace();
    }
    }
}
Sample output to retrieve the type of the three public fields in this class (b, name, and the parameterized type list), follows. User input is in italics.

$ java FieldSpy FieldSpy b
Type: class [[Z
GenericType: class [[Z
$ java FieldSpy FieldSpy name
Type: class java.lang.String
GenericType: class java.lang.String
$ java FieldSpy FieldSpy list
Type: interface java.util.List
GenericType: java.util.List<java.lang.Integer>
$ java FieldSpy FieldSpy val
Type: class java.lang.Object
GenericType: T
导入java.lang.reflect.Field; 导入java.util.List; 公共级战地间谍{ 公共布尔值[][]b={{false,false},{true,true}; 公共字符串name=“Alice”; 公开名单; 公共T值; 公共静态void main(字符串…参数){ 试一试{ Class c=Class.forName(args[0]); 字段f=c.getField(args[1]); System.out.format(“类型:%s%n”,f.getType()); System.out.format(“GenericType:%s%n”,f.getGenericType()); //生产代码应该更优雅地处理这些异常 }捕获(ClassNotFoundException x){ x、 printStackTrace(); }捕获(NoSuchFieldException x){ x、 printStackTrace(); } } } 下面是检索此类中三个公共字段(b、名称和参数化类型列表)类型的示例输出。用户输入为斜体。 $java FieldSpy FieldSpy b 类型:类别[[Z] GenericType:class[[Z] $java FieldSpy FieldSpy名称 类型:class java.lang.String GenericType:class java.lang.String $java FieldSpy FieldSpy列表 类型:接口java.util.List GenericType:java.util.List $java FieldSpy FieldSpy val 类型:类java.lang.Object 一般类型:T
一个相当老套的解决方案是在删除导入后将文本放入一个文件中,并使用与公共类不同的名称

然后使用包动态编译文件并捕获

  • 您可以捕获默认Java类的“未定义类”类型的错误
  • 对于您定义的类,如果它是公共类,您将得到一个错误,如“类必须在其自己的文件中定义”
  • 所以最后你会得到

  • 编译错误中类的行号
  • 错误语句中类的名称
  • 从长远来看,这可能过于复杂,但如果没有库来执行OP所述的操作,则可以使用它


    此外,对于
    java.lang
    下的类来说,事情可能会变得棘手,因为它们在默认情况下是包含的

    这可能会起作用,但不幸的是,我处理的是纯文本,所以反射是不存在的:/您可能需要检查
    JBoss Roaster
    及其JDT实现,它允许您解析java源代码。