现在听起来好像你想从规范名称中获取完全限定的名称 (FQN)。由于这与从简单名称工作不同,我将添加第二个答案。
如果会导致规范名称冲突,则 Sun javac 命令将不会编译类。但是,通过单独编译,您仍然可以获得两个具有相同规范名称的不同类。
例如:
文件 src1\com\stack\Test.java
package com.stack;
public class Test {
public static class Example {
public static class Cow {
public static class Hoof {
}
}
}
public static void main(String[] args) throws Exception {
Class<?> cl1 = Class.forName("com.stack.Test$Example$Cow$Hoof");
Class<?> cl2 = Class.forName("com.stack.Test.Example.Cow.Hoof");
System.out.println(cl1.getName());
System.out.println(cl1.getSimpleName());
System.out.println(cl1.getCanonicalName());
System.out.println();
System.out.println(cl2.getName());
System.out.println(cl2.getSimpleName());
System.out.println(cl2.getCanonicalName());
}
}
文件 src2\com\stack\Test\Example\Cow\Hoof.java
package com.stack.Test.Example.Cow;
public class Hoof { }
然后编译并执行:
set CLASSPATH=
mkdir bin1 bin2
javac -d bin1 -sourcepath src1 src1\com\stack\Test.java
javac -d bin2 -sourcepath src2 src2\com\stack\Test\Example\Cow\Hoof.java
set CLASSPATH=bin1;bin2
java com.stack.Test
生成输出:
com.stack.Test$Example$Cow$Hoof
Hoof
com.stack.Test.Example.Cow.Hoof
com.stack.Test.Example.Cow.Hoof
Hoof
com.stack.Test.Example.Cow.Hoof
因此,两个类具有相同的规范名称,但 FQN 不同。即使两个类具有相同的 FQN 和相同的规范名称,如果它们通过不同的类装入器装入,它们仍然可能不同。
为了解决您的问题,我看到了您可以采取的几种前进方式。
首先,您可以指定匹配嵌套量最少的类,从而匹配 FQN 中 “$” 最少的类。更新事实证明,Sun javac与此完全相反,并且匹配具有最多嵌套的类。
其次,您可以测试所有可能的 FQN,如果有多个 FQN,则引发异常。
第三,接受唯一的唯一映射是使用 FQN,然后仅在指定的类装入器中,并适当地重新处理应用程序。我发现使用线程上下文类装入器作为缺省类装入器很方便。