当前位置: 首页 > 知识库问答 >
问题:

如果一个java类只有完全限定的名称,如何获得它的二进制名称?

江鹏
2023-03-14

反射类和方法以及类加载器等都需要使用所谓的“二进制”类名。

package frege;
public static class RT {
    ....
    public static class X { .... }
}

类的完全限定名为frege.rt.x。然而,要获得类对象,需要编写:

Class.forName("frege.RT$X")

而不是

Class.forName("frege.RT.X")    // fails with ClassNotFoundException

因为x恰好是frege.rt的内部类。

共有1个答案

常博裕
2023-03-14

现在听起来像是希望从规范名称中获得完全限定名称(FQN)。因为这与从一个简单的名字开始工作是不同的,所以我将添加第二个答案。

如果会导致规范名称冲突,Sun javac命令将不会编译类。但是,通过单独编译,仍然可以得到两个具有相同规范名称的不同类。

一个例子:

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,如果有多个FQN,则抛出异常。

第三,接受唯一唯一的映射是与FQN的映射,然后只在指定的类加载器中,并适当地重新工作应用程序。我发现使用线程上下文类加载器作为默认类加载器很方便。

 类似资料:
  • 本文向大家介绍Java获取具有其(完全限定的)名称的类,包括了Java获取具有其(完全限定的)名称的类的使用技巧和注意事项,需要的朋友参考一下 示例 给定一个String包含类名的Class对象,可以使用Class.forName以下对象访问它的对象: Java SE 1.2 可以指定是否初始化类(的第二个参数forName)以及ClassLoader应该使用哪个类(第三个参数):

  • 问题内容: 我想获取给定类的所有子类及其完全限定名称的列表。我想从Eclipse复制它并粘贴到这样的文本文件中: 我试过了: 在做。 但是 出于某些奇怪的原因,这个列表没有列出子类的子类,而只列出了直接子孙。 类的打开视图,该视图在树组件中打印所有子类, 但是 此视图不允许我选择所有行并复制其名称。 还有其他技巧吗?有数百种课程,因此我想避免手动进行。 问题答案: 按照http://internn

  • 问题内容: 考虑以下病理示例: 在构造函数中创建的两个实例属于嵌套类。 但是,我怎么能指称我们在同一个班级中都知道和喜欢的东西呢?我们不能导入它,也不能使用完全限定的名称,因为将使用嵌套的类符号。 在这种情况下我们该怎么办?(除了显而易见的以外-停止对嵌套类使用此类肆意的邪恶名称)。 问题答案: 如果您完成了以下两项操作,则不能再直接引用: 在作用域中使用静态嵌套类隐藏简单名称。 使用嵌套在cla

  • 背景:我们正在开发一个与多个第三方Web服务通信的应用程序。遗憾的是,其中一个使用糟糕的命名约定定义了WSDL文件。响应元素及其使用的complexType经常重复使用相同的名称。下面截取的代码显示了一个这样的实例: 我们使用Maven cxf codigen插件(jaxb/jax-ws)来编译Java类。为了避免名称冲突,我们以前使用过选项-AutoName分辨率。然而,我们发现这会导致意想不到

  • 问题内容: 您好在我的Java类Toto中,我有3个静态方法,我想知道当我处于这些方法之一时,如何在try catch bloc中获取和显示package.class.methode的名称?我在methodeA中尝试过: 但它不起作用,我怎么也可以尝试显示它?谢谢 问题答案: -将打印整个异常stracktrace-即所有方法+行号。

  • 如何有效地获得简短的完全限定类名。例如,如果我们通过了“com.test.student”,我们需要得到“c.t.student”。