【问题标题】:Java: Can a parent class statically retrieve the class name of a child class?Java:父类可以静态检索子类的类名吗?
【发布时间】: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 的各种插件的包名称、类。我计划让开发人员对父类进行子类化,并将这个静态字符串与各种请求一起传递给我们的服务。 (不可否认,字符串可能更容易实现相同的目标而不是静态的)。任何其他建议如何实现这一目标?看起来它开始变成一个设计问题......

标签: java class inheritance static classname


【解决方案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();
    }
  }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    相关资源
    最近更新 更多