Abrufen des Namens einer Unterklasse aus einer Oberklasse

Lesezeit: 5 Minuten

Nehmen wir an, ich habe eine Basisklasse mit dem Namen Entity. In dieser Klasse habe ich eine statische Methode, um den Klassennamen abzurufen:

class Entity {
    public static String getClass() {
        return Entity.class.getClass();
    }
}

Jetzt habe ich eine andere Klasse, die das erweitert.

class User extends Entity {
}

Ich möchte den Klassennamen von User erhalten:

System.out.println(User.getClass());

Mein Ziel ist es, die Ausgabe von „com.packagename.User“ an die Konsole zu sehen, aber stattdessen werde ich mit „com.packagename.Entity“ enden, da die Entity-Klasse direkt von der statischen Methode referenziert wird.

Wenn dies keine statische Methode wäre, könnte dies leicht mit der gelöst werden this Schlüsselwort innerhalb der Entity Klasse (also: return this.class.getClass()). Ich brauche diese Methode jedoch, um statisch zu bleiben. Irgendwelche Vorschläge, wie man das angeht?

Machen Sie die Methode nicht statisch. Das Problem ist, dass beim Aufrufen getClass() Sie rufen die Methode in der Superklasse auf – statische Methoden werden nicht vererbt. Darüber hinaus sind Sie im Grunde ein Namensschatten Object.getClass()was verwirrend ist.

Wenn Sie den Klassennamen innerhalb der Superklasse protokollieren müssen, verwenden Sie

return this.getClass().getName();

Dies gibt “Entity” zurück, wenn Sie eine haben Entity Beispiel: “Benutzer”, wenn Sie eine haben User Beispiel usw.

  • this existiert nicht in einer statischen Methode.

    – Matt Huggins

    5. August 2010 um 19:03 Uhr

  • @Matt Huggins, deshalb sagt der erste Satz in meiner Antwort Don't make the method static

    – matt b

    5. August 2010 um 20:10 Uhr

  • @mattb – darum geht es im vorletzten Satz meiner Frage However, I need this method to remain static.

    – Matt Huggins

    19. Januar 2012 um 2:05 Uhr


  • @MattHuggins Ich frage mich, warum eine Pojo-Methode nicht funktionieren würde. Wenn Sie eine statische Methode aufrufen, müssen Sie bereits im Code auf den Klassennamen verweisen. Wenn Sie die Unterklasse instanziiert haben, aber die Referenz von der Oberklasse stammt, haben Sie ein Objekt und müssen die statische Methode nicht aufrufen.

    – Mindwin

    15. Juli 2015 um 14:52 Uhr

  • Auch wenn diese Antwort nicht auf “Ich brauche diese Methode, um statisch zu bleiben” abzielt, ist sie nützlich, wenn Sie (wie ich) hier gelandet sind und nach einer Methode gesucht haben, um die Klasse in einer Methode zu erhalten, die nicht statisch sein musste. 😉

    – Ryan Heathcote

    30. September 2016 um 3:07 Uhr

Benutzer-Avatar
Michael Borgwart

Nicht möglich. Statische Methoden sind in keiner Weise laufzeitpolymorph. Es ist absolut unmöglich, diese Fälle zu unterscheiden:

System.out.println(Entity.getClass());
System.out.println(User.getClass());

Sie werden in denselben Bytecode kompiliert (vorausgesetzt, die Methode ist in definiert Entity).

Außerdem, wie würden Sie diese Methode so nennen, dass sie polymorph ist?

  • Danke für die Klarstellung, ich glaube, ich weiß nicht genug darüber, wie statische Methoden kompiliert werden. Das hilft bei der Klärung, ich muss an einer alternativen Lösung arbeiten.

    – Matt Huggins

    5. August 2010 um 19:04 Uhr

  • +1, genau richtig. Diese ganze Frage ist aus einem Missverständnis darüber entstanden, wie statische Methoden funktionieren.

    – Markus Peters

    5. August 2010 um 19:28 Uhr

Benutzer-Avatar
sirolf2009

Das funktioniert für mich

this.getClass().asSubclass(this.getClass())

Aber ich bin mir nicht sicher, wie es funktioniert.

Ihre Frage ist mehrdeutig, aber soweit ich das beurteilen kann, möchten Sie die aktuelle Klasse von einer statischen Methode wissen. Die Tatsache, dass Klassen voneinander erben, ist irrelevant, aber der Diskussion halber habe ich es auch so implementiert.

class Parent {
    public static void printClass() {
      System.out.println(Thread.currentThread().getStackTrace()[2].getClassName());
    }
}

public class Test extends Parent {
    public static void main(String[] args) {
      printClass();
    }
}

Benutzer-Avatar
Brian S

Die Oberklasse sollte nicht einmal von der Existenz der Unterklasse wissen, geschweige denn Operationen ausführen, die auf dem vollständig qualifizierten Namen der Unterklasse basieren. Wenn Sie Operationen basierend auf der genauen Klasse benötigen und die erforderliche Funktion nicht durch Vererbung ausführen können, sollten Sie Folgendes tun:

public class MyClassUtil
{
    public static String doWorkBasedOnClass(Class<?> clazz)
    {
        if(clazz == MyNormalClass.class)
        {
            // Stuff with MyNormalClass
            // Will not work for subclasses of MyNormalClass
        }

        if(isSubclassOf(clazz, MyNormalSuperclass.class))
        {
            // Stuff with MyNormalSuperclass or any subclasses
        }

        // Similar code for interface implementations
    }

    private static boolean isSubclassOf(Class<?> subclass, Class<?> superclass)
    {
        if(subclass == superclass || superclass == Object.class) return true;

        while(subclass != superclass && subclass != Object.class)
        {
            subclass = subclass.getSuperclass();
        }
        return false;
    }
}

(Ungetesteter Code)

Auch diese Klasse kennt ihre eigenen Unterklassen nicht, sondern nutzt die Class Klasse, um Operationen auszuführen. Höchstwahrscheinlich wird es immer noch eng mit Implementierungen verknüpft sein (im Allgemeinen eine schlechte Sache, oder wenn nicht schlecht, dann nicht besonders gut), aber ich denke, eine Struktur wie diese ist besser als eine Oberklasse, die herausfindet, was all ihre Unterklassen sind.

Warum möchten Sie Ihre eigene Methode getClass() implementieren? Sie können einfach verwenden

System.out.println(User.class);

Bearbeiten (um ein wenig zu erläutern): Sie möchten, dass die Methode statisch ist. In diesem Fall müssen Sie die Methode für die Klasse aufrufen, deren Klassenname Sie möchten, sei es die Unterklasse oder die Oberklasse. Dann statt anzurufen MyClass.getClass()du kannst einfach anrufen MyClass.class oder MyClass.class.getName().

Außerdem erstellen Sie eine static Methode mit der gleichen Signatur wie die Object.getClass() Instanzmethode, die nicht kompiliert wird.

  1. Erstellen Sie eine Member-String-Variable in der Superklasse.
  2. Fügen Sie this.getClass().getName() einem Konstruktor hinzu, der den Wert in der Member-String-Variablen speichert.
  3. Erstellen Sie einen Getter, um den Namen zurückzugeben.

Jedes Mal, wenn die erweiterte Klasse instanziiert wird, wird ihr Name im String gespeichert und ist mit dem Getter zugänglich.

1256200cookie-checkAbrufen des Namens einer Unterklasse aus einer Oberklasse

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy