Вы можете добавить «Класс» в качестве первого параметра и перегрузить метод журнала:
public class SomeClass {
// Usage test:
public static void main( String [] args ) {
log( SomeClass.class, "Hola" );
log( new java.util.Date(), "Hola" );
}
// Object version would call Class method...
public static void log( Object o , String msg ) {
log( o.getClass(), msg );
}
public static void log( Class c , String message ) {
System.out.println( c.getSimpleName() + " " + message );
}
}
Выход:
$ java SomeClass
SomeClass Hola
Date Hola
Но плохо, когда вызывающий класс передается в качестве первого аргумента. Вот где объектно-ориентированная модель вступает в игру как противоположность «процедурному» стилю.
Вы можете получить вызывающий класс, используя трассировку стека, но, как вы отметили, возникнут издержки, если вы вызовете его тысячи раз.
Но если вы создаете переменную класса, тогда для класса будет только один экземпляр, если у вас будет 1000 классов, использующих эту утилиту, у вас будет не более 1000 вызовов.
Что-то вроде этого было бы лучше (тонкий вариант этого другого ответа):
public class LogUtility {
private final String loggingFrom;
public static LogUtility getLogger() {
StackTraceElement [] s = new RuntimeException().getStackTrace();
return new LogUtility( s[1].getClassName() );
}
private LogUtility( String loggingClassName ) {
this.loggingFrom = "("+loggingClassName+") ";
}
public void log( String message ) {
System.out.println( loggingFrom + message );
}
}
Тест использования:
class UsageClass {
private static final LogUtility logger = LogUtility.getLogger();
public static void main( String [] args ) {
UsageClass usageClass = new UsageClass();
usageClass.methodOne();
usageClass.methodTwo();
usageClass.methodThree();
}
private void methodOne() {
logger.log("One");
}
private void methodTwo() {
logger.log("Two");
}
private void methodThree() {
logger.log("Three");
}
}
Мощно
$ java UsageClass
(UsageClass) One
(UsageClass) Two
(UsageClass) Three
Обратите внимание на объявление:
....
class UsageClass {
// This is invoked only once. When the class is first loaded.
private static final LogUtility logger = LogUtility.getLogger();
....
Таким образом, не имеет значения, используете ли вы «регистратор» из objectA, objectB, objectC или из метода класса (например, main), у всех них будет один экземпляр регистратора.