2009-07-02 5 views
9

Mein Java ist rostig, also bitte mit mir ertragen. Ich kann in C tun:Verwendung der aktuellen Klasse in Java statische Methode Erklärung

int someFunc(void) 
{ 
    printf("I'm in %s\n", __func__); 
} 

In Java kann ich lexikalisch auf den Namen oder die Klasse des Typs erhalten derzeit definiert. Zum Beispiel, wenn ich habe:

import org.apache.log4j.Logger; 

class myClass { 
    private static final Logger logger = Logger.getLogger(myClass.class); 
... 
} 

Es scheint falsch "myClass" in dem getLogger() Argumente zu wiederholen. Ich möchte "getLogger (__ CLASS__)" oder "getLogger (this.class)" oder so etwas. (Ich weiß, dass beide dumm sind, aber sie sollten auf das zeigen, wonach ich suche.) Weiß der Java-Compiler wirklich nicht, in welcher Klasse er sich gerade befindet, während er die Quelle verarbeitet?

+0

Sie es auch als Instanzvariable haben zu bekommen könnten und verwenden „this.getClass() ". Die Verwendung des Instanzattributs wäre eine bessere Idee, es sei denn, Sie benötigen es als Klassenattribut. – OscarRyz

+0

der Compiler weiß, welche Klasse es ist, aber wussten Sie nicht, welche Klasse Sie schreiben? Entschuldigung, nur Spaß ... Ich hatte dieses Problem - fast den gleichen Code - aber ich habe nichts besseres gefunden als MyClass.class: -/brauche eine schöne IDE mit Code-Vorlagen und Refactoring ... –

+0

Ich wünsche mir Java hatte das. Ich würde die Syntax 'static.class' empfehlen. – Boann

Antwort

9

Leider gibt es keinen einfacheren Weg, wenn Sie in einem static Kontext sind (wie Sie hier sind). Wenn der Logger eine Instanzvariable wäre, könnten Sie getClass() verwenden, aber dann müssten Sie sich über Unterklassen Gedanken machen.

Für diesen speziellen Fall ist eine Alternative log5j stattdessen zu verwenden. log5j ist ein Wrapper um log4j mit Convenience-Methoden wie getLogger(), der die korrekte Klasse durch den Stapel nach oben leitet. So würde Ihr Code werden:

import com.spinn3r.log5j.Logger; 
class myClass { 
    private static final Logger logger = Logger.getLogger(); 
    ... 
} 

Und Sie können copy-and-paste die gleiche Erklärung in allen Klassen ohne Probleme.

6

Ich konnte nicht widerstehen.

Hier ist die Umsetzung dessen, was mmyers bezieht sich aber nach Hause gemacht :)

Grundsätzlich Sie eine Ausnahme aus, und das zweite Element des Stapels zu erhalten, um den Klassennamen zu bekommen.

Ich denke immer noch, es ist besser, es als Instanz Mitglied zu haben.

:)

package some.utility.packagename; 
import java.util.logging.Logger; 

import some.other.packagename.MyClass; 

public class LoggerFactory { 
    public static Logger getLogger() { 
     StackTraceElement [] s = new RuntimeException().getStackTrace(); 
     return Logger.getLogger(s[1].getClassName()); 
    } 
    public static void main (String [] args) { 
     MyClass a = new MyClass(); 
    } 
} 

Verbrauch:

package some.other.packagename; 
import java.util.logging.Logger; 

import static some.utility.packagename.LoggerFactory.getLogger; 

public class MyClass { 

    private static final Logger logger = getLogger(); 
    static{ 
     System.out.println(MyClass.logger.getName()); 
    } 

} 
+0

Das sieht ungefähr so ​​aus wie mein eigener selbstgebauter Logging Wrapper. :) –

4
StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 
return trace[2].getClassName(); 

IMHO mehr nette Art und Weise Stack-Trace