现在看起来您想从规范名称中获取完全限定名称(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,然后重新设计您的应用程序。我发现将线程上下文类加载器作为默认类加载器很方便。
forName
方法是否需要所谓的“二进制名称”。文档说它使用完全限定名称。 - Edwin DalorzoClass.getName()
返回的是二进制名称。这是一个非常有趣的问题。我还没有找到将您的规范名称转换为二进制名称的方法。我会收藏这个问题,因为我希望最终有人能够提供答案。 - Edwin Dalorzo