P45 Imminent
P45 Imminent

Reputation: 8591

Getting the name of a child class within the base class constructor

Suppose I have an abstract class

public abstract class Foo

and a single constructor

public Foo()
{
}

Given that this constructor must have been called from the construction of a child class, is there a way of recovering the name of that child class within the Foo constructor?

I'd rather not do something evil with the stack trace.

Upvotes: 4

Views: 1981

Answers (6)

Patrick
Patrick

Reputation: 35224

If you want the name of the class like getClass().getSimpleName() it suffice to just use

public Foo() {
  declaredClassname = this.getClass().getSimpleName();
}

because of polymorphy it will always call getClass() from the child class.

Upvotes: 4

Akshay Chugh
Akshay Chugh

Reputation: 31

You can simply call the getClass() function on the object for which you want to know the class. So in your case you would do something like this:

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

Upvotes: 0

Christian Hujer
Christian Hujer

Reputation: 17945

In case you're in a class hierarchy and you want to know the class that actually is constructed, you can use getClass(). In case you want to know the "topmost" class instead of the "bottommost" class, iterate over the superclasses until before you find your own class.

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
    }
}

Upvotes: 0

brso05
brso05

Reputation: 13222

You could get it in the subclass constructor and pass it as a String to the super class constructor:

public foo(String className)
{
}

//subclass constructor
public subclass()
{
     super("subclass");
}

Or you could do:

public foo(String className)
{
}

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

Upvotes: 0

Joop Eggen
Joop Eggen

Reputation: 109547

Of course:

getClass()

But notice that the child class instance (i.e. its fields) still is not initialized, and will be done after the base class constructor. Also do not call overridable methods for the same reason.

Execution of child class constructor:

  1. super() or super(...) constructor
  2. fields that are initialized Xxx xxx = ...;
  3. rest of constructor code

Upvotes: 1

giorashc
giorashc

Reputation: 13713

You can use the following :

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

Upvotes: 1

Related Questions