Java:父类可以静态检索子类的类名吗?

Posted

技术标签:

【中文标题】Java:父类可以静态检索子类的类名吗?【英文标题】:Java: Can a parent class statically retrieve the class name of a child class? 【发布时间】:2011-06-09 23:43:24 【问题描述】:

关于Java,我想静态地知道当前类的类名。 A是B的父类。我想在A(父类)中有一个包含当前类的类名的静态字符串,但是当在B(子类)中引用这个静态字符串时,它应该包含B 的类名。这可能吗?

例子:

public class Parent 

protected static String MY_CLASS_NAME = ???
.
.
.


public class Child extends Parent 

public void testMethod() 
     if (MY_CLASS_NAME.equals(getClass().getName())) 
        System.out.println("We're equal!");
     



【问题讨论】:

你为什么要这样做,因为你可以通过其他方式获得类名? 我有时也希望这也是可能的。但事实并非如此。 static 这个词已经意味着一个成员/方法等被静态地链接到持有它的类。您不能覆盖它 - 例如当链接完成时动态成员/方法 Abstract variables in Java? 的可能重复项 你会怎么用,测试方法真的不多说。 我正在编写一个供其他开发人员使用的 API,并且我想要一些方法来验证使用该 API 的各种插件的包名称、类。我计划让开发人员对父类进行子类化,并将这个静态字符串与各种请求一起传递给我们的服务。 (不可否认,字符串可能更容易实现相同的目标而不是静态的)。任何其他建议如何实现这一目标?看起来它开始变成一个设计问题...... 【参考方案1】:

我知道的唯一方法是: 在父类中创建接受字符串的受保护构造函数。

class Parent 
    private final String className;
    protected Parent(String className) 
         this.className = className;
    


public class Child extends Parent 
    public Child() 
        super("Child");
    

顺便说一句,您甚至可以在 paren 的 custructor 中使用 new Throwable().getStackTrace() 来改进它。在这种情况下,您甚至不必强制所有子级将其姓名传递给父级。

class Parent 
    private final String className;
    protected Parent() 
         StackTraceElement[] trace = new Throwable().getStackTrace();
         this.className = trace[1].getClassName();
    

【讨论】:

哦,这闻起来很腥! trace[1].getClassName(); ... 不错的主意 :) 如果你无论如何都想去这个 hacky 方向,我宁愿使用Thread#getStackTrace(),因为这样可以避免不必要且相对昂贵的异常构造和堆栈跟踪的克隆。提供带参数的抽象构造函数是 IMO 的必经之路。 @BalusC:抽象构造函数的缺点是,每个实例都包含一个字符串的副本——与静态字段相比,这是一种内存浪费。 @Chris:如果您将字符串设为常量,则可以忽略不计。另请参阅您自己的答案和链接的可能欺骗。 @BalusC:取决于 - 指针仍然是 4 个字节。对于树中的许多小对象(例如类似 DOM 的结构),我更愿意避免使用它,因为我看不到真正的优势 :-)【参考方案2】:

不,这是不可能的。静态字符串只有一个副本(每个 ClassLoader),但您可以有多个子类。

但是,您可以为每个(子)类设置一个静态字段,然后使用方法

public class Child extends Parent 
   private static final String NAME = "some alias";

   @Override
   public String getName() 
       return NAME;
   

这是一种可用于避免反射的技术(名称通常不等于类名,但使用了一些别名 - 它也可以用于枚举而不是字符串)。

【讨论】:

非常感谢 :) 只有我得到的东西 packagename.class 这不是问题,但这很有帮助【参考方案3】:

尽管你不能使用静态变量来尝试这段代码

  class Parent
    final String className;
    public Parent()
     className=this.getClass().getName();
    
  

并为所需的子类执行此操作

【讨论】:

以上是关于Java:父类可以静态检索子类的类名吗?的主要内容,如果未能解决你的问题,请参考以下文章

java中私有的属性、静态成员可以被子类继承吗?

C++可不可以让子类继承父类的静态成员后赋予它各自不同的值?

Java实例化对象时的初始化

java中静态属性和和静态方法的继承问题 以及多态的实质

PHP 父类静态方法中调用子类静态方法

请教一下C#中父类静态构造函数在子类中为啥不会和子类的静态构造函数一起执行