在不加载类的情况下近似class.getSimpleName()的最佳方式是什么?

给定一个可以用Class.forName()加载的完全限定的类名,是否有一种方法可以将名称转换为加载类并调用getSimpleName()而不实际尝试加载类的结果? 我需要这个功能来进行反射。


我要说的是,你不能仅仅根据名字来做它。

你可以尝试拆分.$ ,但这个示例代码表明,在简单名称开始的地方并不总是显而易见的:

class Ideone
{
    private static class Bar {};

    public static void main (String[] args) throws java.lang.Exception
    {
      class Foo$o {
        class Bar$bar {}
      };
      class Foo$o$Bar {
        class Bar$bar {}
      };
      class Foo$o$Bar$Bar$bar {}
      print(Ideone.class);
      print(Bar.class);
      print(Foo$o.class);
      print(Foo$o.Bar$bar.class);
      print(Foo$o$Bar.Bar$bar.class);
      print(Foo$o$Bar$Bar$bar.class);
    }

    private static void print(Class<?> clazz) {
        System.out.printf("fqn=%s, sn=%s%n", clazz.getName(), clazz.getSimpleName());
    }
}

输出:

fqn=Ideone, sn=Ideone
fqn=Ideone$Bar, sn=Bar
fqn=Ideone$1Foo$o, sn=Foo$o
fqn=Ideone$1Foo$o$Bar$bar, sn=Bar$bar
fqn=Ideone$1Foo$o$Bar$Bar$bar, sn=Bar$bar
fqn=Ideone$2Foo$o$Bar$Bar$bar, sn=Foo$o$Bar$Bar$bar

Ideone演示

也就是说,如果你说“这个名字的决赛后位$. ”,你就错了。

唯一可行的方法是加载类,可能不需要初始化它:

Class<?> clazz = Class.forName(className, false, someClassLoadeR);

正如@AndyTurner的回答所证明的那样,在所有情况下,您都无法从限定的类字符串中派生简单名称。

但是,如果没有实际尝试加载类的约束不禁止读取类文件的内容,则可以执行以下操作(对于边缘案例):

  • 通过Class.getResourceAsStream()获取类文件内容的InputStream
  • 解析类文件的开头并从常量池中读取超类名。
  • (如@shmosel所述)实现Class.getSimpleName()的逻辑。 超级类名允许您替换依赖于已经加载的类的Class.getSimpleBinaryString()
  • 链接地址: http://www.djcxy.com/p/91405.html

    上一篇: What is the best way to approximate class.getSimpleName() without loading class?

    下一篇: Can Identifiers be duplicated across cases of a variant record in FreePascal?