2

My question is intentionally titled nearly exactly like this one, but what I want is to strip the package name and nothing else. My classes look like

class AProperlyAndDescriptivelyNamedClass {
    class First {...}
    class Next {...}
    class Last {...}
}

class AnotherTopLevelLongNamedClass {
    class First {...}
    class Next {...}
    class Last {...}
}

As you can see, I'm using some long and descriptive class names for my top-level classes and repeating all the stuff in the nested classes would be pretty nonsensical. Using some strange shortcut would be no better. I always refer to the classes using their enclosing class (and no package) and that's how I want to print them too.

I know I could get the package name and strip a corresponding number of characters from the full class name, but I guess somebody did it already?

Community
  • 1
  • 1
maaartinus
  • 44,714
  • 32
  • 161
  • 320

4 Answers4

3

I guess you need to implement a short method like this:

private static String getSimpleName(Class<?> clazz) {
    String simpleName = clazz.getSimpleName();
    if (clazz.isMemberClass()) {
        Class<?> enclosingClass = clazz.getEnclosingClass();
        simpleName = enclosingClass.getSimpleName() + "." + simpleName;
    }
    return simpleName;
}

Then

String simpleName = getSimpleName(AnotherTopLevelLongNamedClass.First.class);
System.out.println(simpleName);

will Output

AnotherTopLevelLongNamedClass.First
René Link
  • 48,224
  • 13
  • 108
  • 140
  • The above solution will only work with one level of enclosure, whereas `cls.getName().replace(cls.getPackageName() + ".", "")` is simpler and works with multiple levels. – Easty77 Dec 08 '22 at 10:54
2

There is a method getSimpleName() in java.lang.Class<T>, which does indeed return only the name of the class.

Source

Krumuvecis
  • 121
  • 3
0

Have a look at this:

    public static String findName (Object o){
        List<String> list = new ArrayList<String>();
        Class<? extends Object> clazz = o.getClass();

        list.add(clazz.getSimpleName());
        while (clazz.getEnclosingClass() != null) {
            clazz = clazz.getEnclosingClass();
            list.add(clazz.getSimpleName());
        }

        StringBuilder builder = new StringBuilder();
        for (int i=list.size()-1; i>=0; i--){
            builder.append(list.get(i));
            builder.append(".");
        }
        builder.delete(builder.length()-1, builder.length());
        return builder.toString();

    }
dsafcdsge4rfdse
  • 260
  • 2
  • 12
0

Already you describe the best method, I think.

I know I could get the package name and strip a corresponding number of characters from the full class name, but I guess somebody did it already?

The earlier answers don’t take this approach, but I think they suffer for it. Roughly it would be:

cl.getName().substring( cl.getPackageName().length() )

Taking account of edge cases, here’s an implementation:

/** Returns `cl.getName` stripped of any leading package qualifier.
  */
String nameWithoutPackage( Class cl ) {
    String name = cl.getName();
    if( !cl.isArray() ) { // Then a package qualifier might lead the name.
        int strip = cl.getPackageName().length();
        if( strip > 0 ) name = name.substring( strip + /*dot separator*/1 ); }
    return name; }
Michael Allan
  • 3,731
  • 23
  • 31