Java 获取基类构造函数中的子类的名称

Java 获取基类构造函数中的子类的名称,java,Java,假设我有一个抽象类 公共抽象类Foo 和一个构造函数 public Foo() { } 鉴于此构造函数必须是从子类的构造中调用的,是否有方法在Foo构造函数中恢复该子类的名称 我不想对堆栈跟踪做坏事。您可以在子类构造函数中获取它,并将其作为字符串传递给超级类构造函数: public foo(String className) { } //subclass constructor public subclass() { super("subclass"); } 或者你可以: pub

假设我有一个抽象类

公共抽象类Foo

和一个构造函数

public Foo()
{
}
鉴于此构造函数必须是从子类的构造中调用的,是否有方法在
Foo
构造函数中恢复该子类的名称


我不想对堆栈跟踪做坏事。

您可以在子类构造函数中获取它,并将其作为字符串传递给超级类构造函数:

public foo(String className)
{
}

//subclass constructor
public subclass()
{
     super("subclass");
}
或者你可以:

public foo(String className)
{
}

//subclass constructor
public subclass()
{
     super(this.getClass().getSimpleName());
}

您可以使用以下选项:

public Foo()
{
    System.out.println(this.getClass().getSimpleName())
}

如果您想要类的名称,比如
getClass().getSimpleName()
,只需使用

public Foo() {
  declaredClassname = this.getClass().getSimpleName();
}
由于多态性,它总是从子类调用getClass()。

当然:

getClass()
但是请注意,子类实例(即其字段)仍然没有初始化,将在基类构造函数之后完成。也不要出于同样的原因调用可重写的方法

子类构造函数的执行:

public foo(String className)
{
}

//subclass constructor
public subclass()
{
     super("subclass");
}
  • super()或super(…)构造函数
  • 初始化的字段
    Xxx Xxx=
  • 构造函数代码的其余部分

  • 如果您处于类层次结构中,并且希望知道实际构造的类,则可以使用getClass()。 如果您想知道“最上面的”类而不是“最下面的”类,请在找到自己的类之前迭代超类

    import static java.lang.System.err;
    abstract class A {
        protected A() {
            err.format("%s %s%n", getClass().getName(), getTopMostSubclass().getName());
        }
        Class<? extends A> getTopMostSubclass() {
            Class<?> previousClass = getClass(), currentClass;
            while (!A.class.equals(currentClass = previousClass.getSuperclass()))
                previousClass = currentClass;
            return (Class<? extends A>) previousClass;
        }
    }
    class B extends A {}
    class C extends B {}
    public class Main {
        public static void main(final String... args) {
            new B(); // prints B B
            new C(); // prints C B
        }
    }
    
    导入静态java.lang.System.err;
    抽象A类{
    保护A(){
    错误格式(“%s%s%n”、getClass().getName()、getTopMostSubclass().getName());
    }
    类previousClass=getClass(),currentClass;
    而(!A.class.equals(currentClass=previousClass.getSuperclass())
    previousClass=currentClass;
    
    return(Class您只需在您想要了解其类的对象上调用getClass()函数即可

    abstract class ParentClass {
        public ParentClass() {
            System.out.println(this.getClass().getName());
        }
        public String doSomething() {
            return "Hello";
        }
    }
    
    class ChildClass extends ParentClass {
    }
    
    ...
    ...
    
    ChildClass obj = new ChildClass();// will output  ChildClass
    

    如果没有stacktrace,这非常困难,除非您将其作为param传递,否则这确实不是一个好的解决方案getClass().getSimpleName()仅与子类一样工作当存在更简单的解决方案时,它会增加复杂性这是一个好的解决方案。问题是超级类构造函数需要子类的名称。一个小建议是使用
    this.getClass().getSimpleName()
    而不是
    super
    调用中的字符串literal
    子类
    。@brso05向基类添加参数会增加复杂性,无论它有多简单。此外,您还需要在每个子类的构造函数中添加一行额外的代码。这就是为什么它是一个解决方案,但不是一个好的解决方案。当然,我会一直使用它。是的,我是苏在couchDb实体中,我使用它,您需要一个类型属性来选择它们,我只使用这个apporach(在基类的构造函数中设置
    setDbType(this.getClass().getSimpleName();
    (所有实体的超级构造函数)),虽然它不是抽象的,但这不应该有什么区别