Alex Rivera | Logout

Getting the class name from a static method in Java

Asked 2009-06-01T20:42:16.660
301

How can one get the name of the class from a static method in that class. For example

public class MyClass {
    public static String getClassName() {
        String name = ????; // what goes here so the string "MyClass" is returned
        return name;
    }
}

To put it in context, I actually want to return the class name as part of a message in an exception.

Edit
Report

2 Answers

35

You could do something really sweet by using JNI like this:

MyObject.java:

public class MyObject
{
    static
    {
        System.loadLibrary( "classname" );
    }

    public static native String getClassName();

    public static void main( String[] args )
    {
        System.out.println( getClassName() );
    }
}

then:

javac MyObject.java
javah -jni MyObject

then:

MyObject.c:

#include "MyObject.h"

JNIEXPORT jstring JNICALL Java_MyObject_getClassName( JNIEnv *env, jclass cls )
{
    jclass javaLangClass = (*env)->FindClass( env, "java/lang/Class" );
    jmethodID getName = (*env)->GetMethodID( env, javaLangClass, "getName",
        "()Ljava/lang/String;" );
    return (*env)->CallObjectMethod( env, cls, getName );
}

Then compile the C up into a shared library called libclassname.so and run the java!

*chuckle

answered 2011-08-05T21:20:49.533
7

Verbatim use of caller's class like MyClass.class.getName() actually does the job, but is prone to copy/paste errors if you propagate this code to numerous classes/subclasses where you need this class name.

And Tom Hawtin's recipe is in fact not bad, one just needs to cook it the right way :)

In case you have a base class with a static method that may be called from subclasses, and this static method needs to know the actual caller's class, this may be achieved like the following:

class BaseClass {
  static sharedStaticMethod (String callerClassName, Object... otherArgs) {
    useCallerClassNameAsYouWish (callerClassName);
    // and direct use of 'new Object() { }.getClass().getEnclosingClass().getName()'
    // instead of 'callerClassName' is not going to help here,
    // as it returns "BaseClass"
  }
}

class SubClass1 extends BaseClass {
  static someSubclassStaticMethod () {
    // this call of the shared method is prone to copy/paste errors
    sharedStaticMethod (SubClass1.class.getName(),
                        other_arguments);
    // and this call is safe to copy/paste
    sharedStaticMethod (new Object() { }.getClass().getEnclosingClass().getName(),
                        other_arguments);
  }
}
answered 2013-07-01T03:43:12.773

Your Answer