如果只有一个完全限定的名称,如何获取java类的二进制名称? [英] How to get the binary name of a java class, if one has only the fully qualified name?

查看:358
本文介绍了如果只有一个完全限定的名称,如何获取java类的二进制名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The reflection classes and methods as well as class loaders etc. need the so called "binary" names of classes to work with.

问题是,怎么做一个人获得二进制名称,如果一个人只有一个完全限定的名字,即一个人在源代码中使用的名称。

The question is, how does one get the binary name if one only has the fully qualified name, i.e. the name that one would use in source code.

例如:

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

该类的完全限定名称为 frege.RT.X 。然而,要获得类对象,需要编写:

The fully qualified name of the class would be frege.RT.X. Yet, to get the class object, one needs to write:

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

而不是

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

因为 X 恰好是 frege.RT 的内部类。

一种可能但又笨拙的解决方案是从后面逐个替换 ,直到 Class.forName()不再抛出 ClassNotFoundException 或者没有更多要替换。

A possible, but clumsy, solution would be to replace . with $ from backwards, one by one, until Class.forName() doesn't throw ClassNotFoundException anymore or there are no more . to replace.

有没有更好的/众所周知的/标准解决方案?我查看了API文档中的 CLassLoader java.lang.reflect 但没有找到任何可用的东西。

Is there any better/well known/standard solution? I looked in the API docs for Class, CLassLoader and java.lang.reflect but did not find anything usable.

推荐答案

现在听起来你想获得完全限定的名字( FQN)来自规范名称。由于这与使用简单名称不同,我将添加第二个答案。

It now sounds like you want to get the fully qualified name (FQN) from the canonical name. As that is different from working from a simple name I'll add a second answer.

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

The Sun javac command will not compile a classes if a canonical name conflict would result. However by compiling separately you can still get two different classes with the same canonical name.

示例:

文件src1 \ com\stack \Test.java

File 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 \示例\Cow \Hoof.java

File 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和相同的规范名称,如果它们通过不同的类加载器加载,它们仍然可以不同。

Thus two classes have the same canonical name but different FQNs. Even if two classes have the same FQN and same canonical name, they can still be different if they are loaded via different class loaders.

要解决您的问题,我会看到几种方法你可以采取前进。

To resolve your issue I see several ways forward you could take.

首先你可以指定你匹配具有最少嵌套量的类,因此FQN中的'$'数量最少。 UPDATE 事实证明,Sun javac与此完全相反,并且匹配具有最多嵌套的类。

First you can specify that you match the class with the least amount of nesting and hence the least number of '$'s in the FQN. UPDATE It turns out Sun javac does the exact opposite of this and matches the class with the most nesting.

其次,您可以测试所有可能的FQN如果有多个,则抛出一个异常。

Second you can test all possible FQNs and throw an exception if there is more than one.

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

Third, accept that the only unique mapping is with the FQN then only within a specified class loader and re-work you application appropriately. I find it convenient to use the thread context class loader as a default class loader.

这篇关于如果只有一个完全限定的名称,如何获取java类的二进制名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆