@CallerSensitive as public API ?
Dr Heinz M. Kabutz
heinz at javaspecialists.eu
Wed Jun 26 09:40:24 UTC 2013
Remi Forax wrote:
> On 06/26/2013 03:10 AM, Dr Heinz M. Kabutz wrote:
>> Hi Peter,
>>
>> here is another use case, where someone might want to use this:
>>
>> 3 - in a static context, find out what the class is that you are in.
>>
>> For example, if you want to create a logger, instead of doing this:
>>
>> private static final Logger log = Logger.getLogger(SomeClass.class);
>>
>> we could instead have a magic method that figures out what class this
>> is being called from and then sets the class automatically.
>>
>> There are two other ways to do this, but they are a lot slower than
>> Reflection.getCallerClass():
>>
>> 1. http://www.javaspecialists.eu/archive/Issue137.html - create an
>> exception and figure out who the calling class is
>>
>> 2. Or we can use the SecurityManager to get us a stack of contexts.
>>
>> For example, in the exercises for my courses, some students had
>> problems with the JUnit plugin. So each test case also contains the
>> main method, but it is always the same:
>>
>> public static void main(String[] args) {
>> UnitTestRunner.run();
>> }
>>
>> My UnitTestRunner then depends on the security manager to decide what
>> the actual class is and then uses the JUnit4TestAdapter to call the
>> methods:
>>
>> import junit.framework.*;
>> import junit.textui.*;
>>
>> public class UnitTestRunner {
>> private static void run(Class clazz) {
>> System.out.println("Running unit tests for " + clazz);
>> TestRunner.run(new JUnit4TestAdapter(clazz));
>> }
>>
>> public static void run() {
>> MySecurityManager sm = new MySecurityManager();
>> Class clazz = sm.getClassContext()[2];
>> run(clazz);
>> }
>>
>> private static class MySecurityManager extends SecurityManager {
>> public Class[] getClassContext() {
>> return super.getClassContext();
>> }
>> }
>> }
>>
>> Works like a charm. Fortunately this is not affected by the
>> Reflection.getCallerClass() bug.
>>
>> Just my 2c :-)
>>
>> Regards
>>
>> Heinz
>
> Hi Heinz,
> You can also use the JSR 292 Lookup object
> MethodHandles.lookup().lookupClass()
>
Brilliant, thanks Rémi! I've learned something new :-)
However, in this case it would not work as I need to find the calling
class, not the UnitTestRunner class. Is there a way to find out which
class called you with MethodHandles?
Heinz
More information about the core-libs-dev
mailing list