开发者

Java - Class type from inside static initialization block

Is it possible to get the class type from inside the static initialization block?

This is a simplified version of what I currently have::

class Person extends SuperClass {

   String firstName;

   static{
      // This function is on the "SuperClass":
      //  I'd for this function to be able to get "Person.class" without me
      //  having to explicitly type it in but "this.class" does not work in 
      //  a static context.
      doSomeReflectionStuff(Person.class);     // IN "SuperClass"
   }
}

This is closer to what I am doing, which is to initialize a data structure that holds information about the object and its annotations, etc... Perhaps I am using the wrong pattern?

public abstract SuperClass{
   static void doSomeReflectionStuff( Class<?> classType, List<FieldData> fieldDataList ){
      Field[] fields = classType.getDeclaredFields();
      for( Field field : fields ){
         // Initialize fieldDataList
      }
   }
}

public abstract class Person {

   @SomeAnnotation
   String firstName;

   // Holds information on each of the fields, I used a Map<String, FieldData>
   //  in my actual implementation to map strings to the field information, but that
   //  seemed a little wordy for this example
   static List<FieldData> fieldDataList = new List<FieldData>();

   static{
      // Again, it seems dangerous to have to type in the "Person.class"
      //   (or Address.class, PhoneNumber.class, etc...) every time.
      //   Ideally, I'd liken to eliminate all this code from the Sub class
      //   since now I have to copy and pas开发者_开发百科te it into each Sub class.
      doSomeReflectionStuff(Person.class, fieldDataList);
   }
}

Edit

I picked the accepted answer based on what applied best to my problem, however it seems to me that all three of the current answers have their merits.


No, it's not possible without grabbing the stacktrace (which is imo nastier than your initial approach and for which I would in any way prefer Thread#getStackTrace() above new Exception()).

Rather do that job in a non-static initializer (or the default constructor) of the abstract class where you check the initialized status.

public abstract class SuperClass {

    {
        if (!isInitialized(getClass())) {
            initialize(getClass());
        }
    }

}

The called methods in turn can be safely static.


yes, I use this often to initialize a static Log variable :

e.g. :

public class Project implements Serializable, Cloneable, Comparable<Project> {
    private static final Logger LOG = LoggerFactory.getLogger(Project.class);
    ...


To get a class at runtime, you could do something along the lines of

public class Test {
public static void main(String[] args) {
    try{
        throw new Exception();
    }
    catch(Exception e){
        StackTraceElement[] sTrace = e.getStackTrace();
        // sTrace[0] will be always there
        String className = sTrace[0].getClassName();
        System.out.println(className);

    }
}

}

Not pretty but will do the job (ripped from http://www.artima.com/forums/flat.jsp?forum=1&thread=155230).

This means you still make a call from the subclass (so is in the stack trace), but you don't need to include the XXX.class as an argument.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜