Klassennamen im statischen Umfeld

Andi_CH

Top Contributor
Ich kann nichts dafür, aber in der Software hier ist beinahe alles statisch.

Kann ich (z.B. für eine Log-Ausgabe) den Klassennamen ermitteln? (Es geht eigentlich nur um Faulheit ;-) copy paste der log-Funktionalitäten)

Ganz elegant wäre, wenn ich trotz ererbter log-Funktionen der Name der Klasse erhalte aus der ich "log" aufrufe.

Bis jetzt wird der Klassename als
Code:
private final static String = "BlaBla";
in jeder Klasse gespeichert und die log-Funktionen gezwungenermassen repliziert, da die Vererbung ja nicht richtig klappt und änderungssicher ist das definitv auch nicht.

Java:
String s = (new Test3()).getClass().getName();
erachte ich irgendwie als suboptimal

(Nein, JLog oder was auch immer kommt nicht in Frage, das würde einen kompletten Systemumbau bedeuten und dafür bekomme ich kein grünes Licht :-( )
 

MarderFahrer

Gesperrter Benutzer
Meine Implementation zu diesem Thema benutzt ebenfalls den Stacktrace um an den Klassennamen zu kommen.

Java:
// Trick to get the class name in a static way
Exception e = new Exception();
StackTraceElement[] sTrace = e.getStackTrace();
// sTrace[0] will be always there
String className = sTrace[0].getClassName();

Nicht sehr elegant aber erfüllt seinen Zweck. :D
 

Murray

Top Contributor
Anstatt aus der Exception sollte man sich den Stack-Trave m.E. besser über
Java:
Thread.currentThread().getStackTrace()
holen.

Ganz ohne den Stack-Trace kommt man aus, wenn man eine anonymous inner class verwendet:
Java:
String ownClsName = new Object(){}.getClass().getEnclosingClass().getName();

Ob das aber "billiger" ist als der Weg über den Stack-Trace, müsste man ggfs. (wenn die Stelle wirklich als performance-kritisch erkannt worden ist) analysieren; schließlich muss auch hier ein Objekt instanziiert und später wieder collected werden.
 

Andi_CH

Top Contributor
Code:
String s = Test3.class.getName();
würde Dir zumindest das erzeugen eines Objektes ersparen ;-)
Aber was wirklich besseres fällt mir grad nicht ein...

Hi hi - da bin ich reingerannt - im Zuge von Refactoring werden einige Klassen auseinandergerissen und der Originalname bleibt der gemeinsamen Vaterklasse - Test3 gibt es aber immer noch.
Abgesehen davon: Wenn ich den Klassennamen verwenden muss um an den Klassennamen zu kommen .... na ja muss wohl nicht weitertippen :)

Ganz elegant wäre halt schon "this".className() .... (logisch, dass es "this" in diesem Kontext nicht gibt.)

Werde wohl den Stacktrace verwenden - geloggt wird hier eigentlich nur in Fehlerfällen und während der Entwicklung - ansonsten ist das per boolean unterdrückt.
 
Zuletzt bearbeitet:
T

Tomate_Salat

Gast
wäre soetwas eine Lösungsmöglichkeit:
Java:
public class App 
{
	public static void main(String[] args)
	{
		Log.info("Hallo welt");
		Demo.doIt();
		Demo demo=new Demo();
		demo.doItInit();
		Log.print();		
	}
}

class Demo
{
	public static void doIt()
	{
		Log.info("test");
	}
	
	public void doItInit()
	{
		Log.info("do ist init");
	}
}

class Log
{
	private StringBuilder log=new StringBuilder();

	private static Log logger=new Log();
	
	public static void info(String text)
	{					
		StackTraceElement caller=Thread.currentThread().getStackTrace()[2];
		
		if(caller!=null) {
			logger.log.append(
				"info|" + caller.getClassName() +  "|" + text + "\n"
			);
		}
	}
	
	public static void print()
	{
		System.out.println(logger.log.toString());
	}
}

Ausgabe:
Code:
info|inf.test.App|Hallo welt
info|inf.test.Demo|test
info|inf.test.Demo|do ist init
?
 
Zuletzt bearbeitet von einem Moderator:

Andi_CH

Top Contributor
An so etwas ähnlichem bin ich gerade dran.

Das ist mehr als Dokumentation für die "Nachwelt" gedacht ;-)

Interessant ist die Tatsache, dass die Exception nur einen Eintrag im StackTraceElement[] liefert (Der zweite der unten gezeigten), der Thread hingegen zwei. Ich werde wohl nach ".java:" suchen

Java:
StackTraceElement[] steArr = Thread.currentThread().getStackTrace();
for (StackTraceElement ste : steArr) {
	System.out.println("----------------------------------------------");
	System.out.println("ste         = " + ste);
	System.out.println("ClassName   = " + ste.getClassName());
	System.out.println("FileName    = " + ste.getFileName());
	System.out.println("LineNumber  = " + ste.getLineNumber());
	System.out.println("MethodeName = " + ste.getMethodName());
}
Code:
----------------------------------------------
ste         = java.lang.Thread.getStackTrace(Unknown Source)
ClassName   = java.lang.Thread
FileName    = null
LineNumber  = -1
MethodeName = getStackTrace
----------------------------------------------
ste         = com.javaforum.test.ShowClassname.main(ShowClassname.java:20)
ClassName   = com.javaforum.test.ShowClassname
FileName    = ShowClassname.java
LineNumber  = 20
MethodeName = main
 

Murray

Top Contributor
Interessant ist die Tatsache, dass die Exception nur einen Eintrag im StackTraceElement[] liefert (Der zweite der unten gezeigten), der Thread hingegen zwei. Ich werde wohl nach ".java:" suchen
Damit würdest du dich darauf verlassen, dass der Bytecode auch solche Informationen enthält - was man beim Compiler mit -g:none allerdings unterdrücken kann. Daher wäre der Code darauf angewiesen, mit bestimmten Compileroptionen übersetzt zu werden.
Aber eigentlich musst du auch nichts suchen: der von Thread.getStackTrace() gelieferte Stack-Trace enthält eben immer am Anfang Thread.getStackTrace. Insofern kannst du davon ausgehen, dass die relevante Information eben bei Index 1 steht.
 
Zuletzt bearbeitet:
T

Tomate_Salat

Gast
dass die relevante Information eben bei Index 1 steht.

fast richtig, sie stehen bei [c]2[/c]. Denn bei index [c]0[/c] steht sowas wie:
[c]java.lang.Thread.getStackTrace(Unknown Source)[/c]
somit steht bei [c]1[/c] die Loggerklasse und bei [c]2[/c] die relevanten Informationen.
 

Murray

Top Contributor
fast richtig, sie stehen bei [c]2[/c]. Denn bei index [c]0[/c] steht sowas wie:
[c]java.lang.Thread.getStackTrace(Unknown Source)[/c]
somit steht bei [c]1[/c] die Loggerklasse und bei [c]2[/c] die relevanten Informationen.
In deinem Beispiel, aber nicht in dem des TOs:

Code:
----------------------------------------------
ste         = java.lang.Thread.getStackTrace(Unknown Source)
ClassName   = java.lang.Thread
FileName    = null
LineNumber  = -1
MethodeName = getStackTrace
----------------------------------------------
ste         = com.javaforum.test.ShowClassname.main(ShowClassname.java:20)
ClassName   = com.javaforum.test.ShowClassname
FileName    = ShowClassname.java
LineNumber  = 20
MethodeName = main
 
T

Tomate_Salat

Gast
Achso ja, ich bin davon ausgegangen, dass der TO es in einer Form verwenden will, wie in meiner Methode. Nach dem Beispiel hattest du dann natürlich recht.
 

Andi_CH

Top Contributor
Das Thema ist wohl soeben gestorben :-(

Erst mal Dampf ablassen:

Es ist zum Kotzen. Verd... warum haben die Javaentwickler Vererbung nicht auch im statischen Umfeld korrekt implementiert ???:L

Ich wollte das alles in der Vaterklasse implementieren und dann auf der Subklasse aufrufen

Das Schei.... Java merkt das nicht und liefert mir den Namen der Vaterklasse.

EDIT: Stimmt nicht alles! Siehe weiter unten.
 
Zuletzt bearbeitet:
T

Tomate_Salat

Gast
Verstehe ich jz nicht so ganz. Meinst sowas in der Art:
Java:
class SLogger
{
	private StringBuilder logs=new StringBuilder();
	
	public void printMe()
	{
		System.out.println(logs.toString());
	}
	
	public void info()
	{
		logs.append(this.getClass() + "\n");
	}
}

class MyLogger extends SLogger
{
	
}
?
Java:
SLogger logger=new MyLogger();
logger.info();
Antwort:
Code:
class inf.test.MyLogger

ansonsten erklärs mal genauer, da findet sich doch bestimmt ein weg.
 
Zuletzt bearbeitet von einem Moderator:

Andi_CH

Top Contributor
Mea culpa - mein Frustausbruch war wohl verfrüht

Java:
public class ShowClassname {
	public static String getClassName() {
		StackTraceElement[] steArr = Thread.currentThread().getStackTrace();
		return steArr[steArr.length-1].getClassName();
	}
}

Java:
public class ShowClassnameSubclass extends ShowClassname {

	public static void main(String[] args) {
		System.out.println(getClassName());
	}
}

und da kommt ganz schön brav:
Code:
com.javaforum.test.ShowClassnameSubclass
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P Klassennamen Konvention Java Basics - Anfänger-Themen 3
Z Erste Schritte Klassennamen ausgeben lassen Java Basics - Anfänger-Themen 2
A Warum immer das "J" im Klassennamen? Java Basics - Anfänger-Themen 10
T Klassen Klassennamen zusammensetzen Java Basics - Anfänger-Themen 3
M Neues Objekt erzeugen mit Klassennamen oder ohne Java Basics - Anfänger-Themen 5
T Klassen Factory und Dynamsiche KlassenNamen Java Basics - Anfänger-Themen 6
S Klassennamen ermitteln Java Basics - Anfänger-Themen 10
G Klassennamen extrahieren Java Basics - Anfänger-Themen 2
R Klassennamen ausgeben Java Basics - Anfänger-Themen 4
S Packetstruktur und Klassennamen auslesen Java Basics - Anfänger-Themen 5
M Aufruf von statischen Methoden einer anderen Klasse Java Basics - Anfänger-Themen 15
Junger_Basileus Celsius -> Fahrenheit / Strukturierung in statischen Methoden Java Basics - Anfänger-Themen 7
D Aufruf einer statischen Variable Java Basics - Anfänger-Themen 1
K Compiler-Fehler Objektmethode aus einer statischen Methode heraus aufrufen Java Basics - Anfänger-Themen 34
K Welchen Typ haben Variablen in Default-Methoden und in statischen Methoden in Schnittstellen? Java Basics - Anfänger-Themen 4
Shams Synchronized-Schlüsselwort bei Inkrementierung einer statischen Variable Java Basics - Anfänger-Themen 13
A Nicht-statische Methode in einer statischen aufrufen Java Basics - Anfänger-Themen 10
T Dynamisches abarbeiten von statischen Methode aus verschiedenen Klassen. Java Basics - Anfänger-Themen 5
N OOP Zugriff auf eine Objekt innerhalb einer Klasse aus statischen Methoden Java Basics - Anfänger-Themen 9
S Gutes Design mit statischen oder Member-Methoden Java Basics - Anfänger-Themen 53
A Parameterübergabe zwischen statischen und nicht statischen Klassen Java Basics - Anfänger-Themen 6
hdi Lebensspanne von statischen Variablen Java Basics - Anfänger-Themen 7
A non-static Methode ausführen in statischen Kontext Java Basics - Anfänger-Themen 17
R Properties über statischen Pfad laden Java Basics - Anfänger-Themen 2
G Warum hat Java keinen statischen Konstruktor? Java Basics - Anfänger-Themen 5
G Problem mit nicht statischen Funktionen Java Basics - Anfänger-Themen 7
S Ergebnisse aus statischen Methoden weiterverwenden Java Basics - Anfänger-Themen 5
M Problem mit nicht statischen Methoden Java Basics - Anfänger-Themen 6
F Verwendung von this in statischen Kontext nicht möglich Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben