What is the best way to approximate class.getSimpleName() without loading class?

Given a fully qualified class name that can be loaded with Class.forName(), is there a way to transform the name into what would be the result of loading the class and invoking getSimpleName() without actually attempting to load the class? I need this capability for reflection purposes.


I'm going to say that you can't do it simply based on the name.

You can try to split on . and $ , but this example code demonstrates that it is not always obvious where the simple name begins:

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());
    }
}

Output:

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 demo

ie if you were to say "the bit of the name after the final $ or . ", you'd be wrong.

The only conclusive way to do this is to load the class, potentially without initializing it:

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

As demonstrated by the answer of @AndyTurner you cannot derive the simple name from the qualified class string in all cases.

But if the constraint without actually attempting to load the class does not forbid to read the contents of the class file, you could do the following (for the edge cases):

  • Get a InputStream for the class file contents via Class.getResourceAsStream()
  • Parse the beginning of the class file and read the super class name from the constant pool.
  • (as commented by @shmosel) Implement the logic of Class.getSimpleName() . The super class name allows you to replace Class.getSimpleBinaryString() which relies on an already loaded class.
  • 链接地址: http://www.djcxy.com/p/91406.html

    上一篇: Twitter OAuth Rest Api状态参数'@'符号

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