Java gem of the day: giving this.getClass() to log4j

jdavidb on 2008-03-12T15:09:36

Today's gem is probably only a gem to me, because it encompasses a realization I should've had a long time ago.

I started using log4j about two month ago. It was very quick to learn since I know log4perl. But I found myself hampered by a few things. In log4perl, you can call getlogger() with no arguments to get the logger for the current package. I used that often and expected to use it more in log4j, but alas it didn't seem to be available. I had to explicitly give the class to getLogger().

And here's where I got confused. I was giving all of my objects a private member named log, which was initialized at declaration. And I was explicitly typing out the class as an argument to getLogger(), e.g., for class MyClass, I was typing:

Logger log = Logger.getLogger(MyClass.class);

This has annoyed me ever since I started using it, because I knew that one day I would cut and paste code from one class to make another class, and being human and fallible I would wind up with one class hardcoded to use another class's logger. Hardcoding is always bad design. But I just didn't see a better way.

Probably anyone semi-literate in Java has already seen the better way by now, but just in case you're slow like me, here's what became obvious today:

Logger log = Logger.getLogger(this.getClass());

You see, for some reason I was under the impression that I couldn't use this in these initializations. I think I thought this was only available in instance methods and constructors or something. Or maybe when I started out I was trying to make log a class variable instead of an instance variable. I can't remember. I remember lamenting that Java didn't have __PACKAGE__ or some similar subclassable way to refer to the current class outside of an instance method. But the obvious fact that these initializations are for instance variables, and that therefore a way to refer to the current instance object might be available, didn't strike me until today.

Papa always said I was oblivious. :)

Incidentally, if I did make log a class variable (static member), I wouldn't have this. If there's a way in that case to programmatically refer to "this class" without explicitly hardcoding the class, I'd appreciate it if someone would enlighten me. I know it's probably obvious. :)