如何在没有包的情况下真正获得类的名称?

Posted

技术标签:

【中文标题】如何在没有包的情况下真正获得类的名称?【英文标题】:How to really get the name of a class without the package? 【发布时间】:2014-01-02 04:55:44 【问题描述】:

我的问题被有意命名为几乎与this one 完全相同,但我想要的是去掉包名而不是别的。我的课看起来像

class AProperlyAndDescriptivelyNamedClass 
    class First ...
    class Next ...
    class Last ...


class AnotherTopLevelLongNamedClass 
    class First ...
    class Next ...
    class Last ...

如您所见,我为我的***类使用了一些长而描述性的类名,而在嵌套类中重复所有内容将是非常荒谬的。使用一些奇怪的快捷方式也不会更好。我总是使用它们的封闭类(而不是包)来引用这些类,这也是我想要打印它们的方式。

我知道我可以获取包名并从完整的类名中删除相应数量的字符,但我猜有人已经这样做了?

【问题讨论】:

【参考方案1】:

我猜你需要实现这样一个简短的方法:

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

然后

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

会输出

AnotherTopLevelLongNamedClass.First

【讨论】:

【参考方案2】:

看看这个:

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

    

【讨论】:

【参考方案3】:

我认为你已经描述了最好的方法。

我知道我可以获取包名并从完整的类名中删除相应数量的字符,但我猜有人已经这样做了?

较早的答案没有采用这种方法,但我认为他们为此受苦。大概是这样的:

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

考虑到边缘情况,这里有一个实现:

/** 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; 

【讨论】:

以上是关于如何在没有包的情况下真正获得类的名称?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有继承方法的情况下获取类的公共方法?

如何在没有虚方法的情况下创建派生类的基类?

如何在没有 Duplexer 包的情况下解决 NodeSchool 的 Duplexer 挑战

如何修复 ImportError:尝试在没有已知父包的情况下进行相对导入

如何在没有“标志”包的情况下在 Go 中获取命令行参数?

Laravel 6 Backpack 4.0:如何在 FormRequest 类中获取当前页面 ID,或者我可以在不使用 FormRequest 类的情况下获得吗?