Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check whether a class is initialized?

You'll probably ask, why would I want to do that - it's because I'm using a class (from an external library) which does stuff in its static initializer and I need to know whether it's been done or not.

I looked at ClassLoader, but didn't find anything that looked useful. Any ideas?

like image 254
mik01aj Avatar asked Sep 09 '10 16:09

mik01aj


4 Answers

You can try something like this:

Class c = new ClassLoader() { Class c = findLoadedClass(className); }.c;

like image 125
Eugene Kuleshov Avatar answered Sep 27 '22 21:09

Eugene Kuleshov


I know it is very late, but I think this answer might be useful. If you are not too scared (and you are allowed) to use the sun.misc.Unsafe class there is a method that precisely does that: The method

sun.misc.Unsafe.shouldBeInitialized(Class)

returns true if and only if the Class provided as parameter is (loaded but) not initialized.

like image 45
Pietro Braione Avatar answered Sep 27 '22 21:09

Pietro Braione


You can use the ClassLoader.findLoadedClass() method. If it returns null, then the class isn't loaded. This way you don't load the class if it wasn't already loaded.


WARNING : This code doesn't really work here, in the system ClassLoader, findLoadedClass() is protected, you need to override it with your own ClassLoader.

Check the link below On the same topic to check if a class is loaded with the system ClassLoader

if(ClassLoader.getSystemClassLoader().findLoadedClass("java.lang.String") != null){
    System.out.println("Yepee, String is loaded !");
}

Very good point from @irreputable :

"loaded" doesn't mean "initialized". initialization only happens at precise moments defined by JLS3 $12.4.1

And I quote :

A class or interface type T will be initialized immediately before the first occurrence of any one of the following:

  • T is a class and an instance of T is created.
  • T is a class and a static method declared by T is invoked.
  • A static field declared by T is assigned.
  • A static field declared by T is used and the field is not a constant variable (§4.12.4).
  • T is a top-level class, and an assert statement (§14.10) lexically nested within T is executed.

Invocation of certain reflective methods in class Class and in package java.lang.reflect also causes class or interface initialization. A class or interface will not be initialized under any other circumstance.


Resources :

  • Javadoc - ClassLoader.findLoadedClass()
  • Internals of Java Class Loading
  • JLS - §12.4.1 When Initialization Occurs

On the same topic :

  • In Java, is it possible to know whether a class has already been loaded?
like image 37
Colin Hebert Avatar answered Sep 27 '22 22:09

Colin Hebert


Why don't you just reference the class (by creating a reference, creating an instance, or accessing a static member)? That will kick off the type initializer if it hasn't already fired and if it has then you are still good to go.

like image 44
Andrew Hare Avatar answered Sep 27 '22 21:09

Andrew Hare