Java - 静态初始化块内部的类类型

发布于 2024-09-04 08:18:59 字数 1603 浏览 6 评论 0原文

是否可以从静态初始化块内部获取类类型?

这是我目前拥有的简化版本::

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"
   }
}

这更接近我正在做的事情,即初始化一个保存有关对象及其注释等信息的数据结构......也许我使用了错误的模式?

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 paste it into each Sub class.
      doSomeReflectionStuff(Person.class, fieldDataList);
   }
}

编辑

我根据最适合我的问题的答案选择了接受的答案,但是在我看来,当前的所有三个答案都有其优点。

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 paste 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

守不住的情 2024-09-11 08:18:59

不,如果不获取堆栈跟踪,这是不可能的(在我看来,这比您最初的方法更糟糕,并且我无论如何都更喜欢 Thread#getStackTrace() 上面 new Exception()) 。

而是在抽象类的非静态初始化程序(或默认构造函数)中完成这项工作,您可以在其中检查初始化状态。

public abstract class SuperClass {

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

}

被调用的方法又可以安全地是静态的。

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.

予囚 2024-09-11 08:18:59

是的,我经常使用它来初始化静态 Log 变量:

例如:

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

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);
    ...
动次打次papapa 2024-09-11 08:18:59

要在运行时获得一个类,您可以按照以下方式执行一些操作

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);

    }
}

}

不太漂亮,但可以完成这项工作(摘自 http://www.artima.com/forums/flat.jsp?forum=1&thread=155230)。

这意味着您仍然从子类进行调用(堆栈跟踪中也是如此),但不需要包含 XXX.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文