0

In my class, I need both an SLF4J Logger with the class as the parameter, as well as a simple class name. Both the logger and CLASS_NAME constants use MethodHandles.lookup(). I was wondering if it makes more sense/is more efficient to have something like this:

private static final Lookup lookup = MethodHandles.lookup();
private static final Logger logger = LoggerFactory.getLogger(lookup.getClass());
private static final String CLASS_NAME = lookup.lookupClass().getSimpleName();

Or just have MethodHandles.lookup() twice:

private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().getClass());
private static final String CLASS_NAME = MethodHandles.lookup().lookupClass().getSimpleName();
moesyzlack23
  • 105
  • 1
  • 11
  • If profiling your application shows that a significant amount of time is being spent in `MethodHandles.lookup()` then you should try to call it less. – tgdavies Aug 20 '21 at 03:52
  • 3
    If you're worried about performance, could you not just use the class literal instead of this reflective approach? – Andy Turner Aug 20 '21 at 06:14

1 Answers1

1

Given these two options, I'd choose the second. There's no reason to maintain a permanent reference to a lookup object if it's never directly needed again. The cost of obtaining the lookup instance is relatively cheap, and this code is only run once -- when the class is initialized.

However, I'm not sure why you're calling lookup in the first place. The normal pattern here is to use a class literal.

By the way, if you really needed to reference a throw-away constant, the best approach is to use a static intializer.

private static final Logger logger;
private static final String CLASS_NAME; 

static {
    var lookup = MethodHandles.lookup();
    logger = LoggerFactory.getLogger(lookup.getClass());
    CLASS_NAME = lookup.lookupClass().getSimpleName();
}
boneill
  • 1,478
  • 1
  • 11
  • 18
  • 2
    I suppose, using `lookup.getClass()` is a bug and it’s supposed to be `lookup.lookupClass()`. In that case, it would make even more sense to use `var type = MethodHandles.lookup().lookupClass(); logger = LoggerFactory.getLogger(type); CLASS_NAME = type.getSimpleName();` But it’s still correct that using a class literal for `type` would be straight-forward (simpler and more efficient). – Holger Aug 23 '21 at 15:59