Angenommen, 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 des Benutzers erhalten:
System.out.println(User.getClass());
Mein Ziel ist es, die Ausgabe von "com.packagename.User" in der Konsole zu sehen, aber stattdessen werde ich "com.packagename.Entity" erhalten, da auf die Entity-Klasse direkt von der statischen Methode verwiesen wird.
Wenn dies keine statische Methode wäre, könnte dies leicht mithilfe des this
Schlüsselworts innerhalb der Entity
Klasse (dh :) gelöst werden 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 Sie beim Aufrufen
getClass()
die Methode in der Superklasse aufrufen - statische Methoden werden nicht vererbt. Darüber hinaus sind Sie im Grunde NamensschattenObject.getClass()
, was verwirrend ist.Wenn Sie den Klassennamen innerhalb der Oberklasse protokollieren müssen, verwenden Sie
return this.getClass().getName();
Dies gibt "Entität" zurück, wenn Sie eine
Entity
Instanz haben, "Benutzer", wenn Sie eineUser
Instanz haben usw.quelle
this
existiert nicht in einer statischen Methode.Don't make the method static
However, I need this method to remain static.
Ihre Frage ist nicht eindeutig, aber soweit ich Ihnen sagen kann, möchten Sie die aktuelle Klasse anhand einer statischen Methode kennen. Die Tatsache, dass Klassen voneinander erben, ist irrelevant, aber für die Diskussion habe ich es auch so implementiert.
quelle
System.out.println(Parent.class.getName());
?extends Parent
den Aufruf entfernen und in ändernParent.printClass()
, wird weiterhin "Test" ausgegeben).Das funktioniert bei mir
this.getClass().asSubclass(this.getClass())
Aber ich bin mir nicht sicher, wie es funktioniert.
quelle
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 benötigen, die auf der genauen Klasse basieren, 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)
Diese Klasse kennt auch ihre eigenen Unterklassen nicht, sondern verwendet die
Class
Klasse zum Ausführen von Operationen. Höchstwahrscheinlich ist es immer noch eng mit Implementierungen verbunden (im Allgemeinen eine schlechte Sache, oder wenn nicht schlecht, ist es nicht besonders gut ), aber ich denke, eine Struktur wie diese ist besser als eine Oberklasse, die herausfindet, was alle ihre Unterklassen sind.quelle
Warum möchten Sie Ihre eigene getClass () -Methode implementieren? Sie können einfach verwenden
Bearbeiten (um etwas näher darauf einzugehen): 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 Superklasse. Anstatt
MyClass.getClass()
anzurufen, können Sie einfachMyClass.class
oder anrufenMyClass.class.getName()
.Außerdem erstellen Sie eine
static
Methode mit derselben Signatur wie dieObject.getClass()
Instanzmethode, die nicht kompiliert werden kann.quelle
static
Methoden wollen, was nicht möglich ist. Können Sie auch erläutern, warum das oben Genannte nicht robust genug ist?User.class.getName()
?User.class.getName()
inEntity
die statische Methode fest codiere , was passiert dann, wenn ichEntity
mit einer neuen Klasse namensProfile
aufrufe? Es wird weiterhin der Klassenname für Benutzer anstelle des Klassennamens für Profil zurückgegeben.Jedes Mal, wenn die erweiterte Klasse instanziiert wird, wird ihr Name in der Zeichenfolge gespeichert und ist mit dem Getter zugänglich.
quelle
Eine statische Methode ist einer Klasse zugeordnet, nicht einem bestimmten Objekt.
Überlegen Sie, wie dies funktionieren würde, wenn mehrere Unterklassen vorhanden wären - z. B. ist Administrator auch eine Entität. Wie würde Ihre statische Entitätsmethode, die nur der Entitätsklasse zugeordnet ist, wissen, welche Unterklasse Sie möchten?
Du könntest:
quelle
Wenn ich Ihre Frage richtig verstehe, können Sie meiner Meinung nach nur das erreichen, was Sie wollen, indem Sie die statische Methode in jeder Unterklasse erneut implementieren, zum Beispiel:
class Entity { public static String getMyClass() { return Entity.class.getName(); } } class Derived extends Entity { public static String getMyClass() { return Derived.class.getName(); } }
Dadurch werden package.Entity und package.Derived nach Bedarf gedruckt. Chaotisch, aber hey, wenn das deine Einschränkungen sind ...
quelle
Wenn ich es richtig mache, möchten Sie Ihre Unterklasse in der Basisklasse in der statischen Methode verwenden. Ich denke, Sie können dies tun, indem Sie einen Klassenparameter an die Methode übergeben
class Entity { public static void useClass(Class c) { System.out.println(c); // to do code here } } class User extends Entity { } class main{ public static void main(String[] args){ Entity.useClass(Entity.class); } }
quelle
Mein Kontext: Entität der Oberklasse mit Unterklassen für XML-Objekte. Meine Lösung: Erstellen Sie eine Klassenvariable in der Oberklasse
Dann würde ich in der Unterklasse die Variable der Oberklasse im Konstruktor setzen
public class SubClass { public SubClass() { claz = this.getClass(); } }
quelle
es ist sehr einfach gemacht von
User.getClass (). GetSuperclass ()
quelle