开发者

What will cause a Java class to be initialized?

I am using the Wrapper Class method to allow me to handle a class either existing or not. When using this technique, it is important to know what will cause my Proxy class to be initialized. In particular, what if I:

  1. Declare an inst开发者_开发百科ance of Proxy without setting it to anything

    public class myClass{ ... Proxy myInst; }

  2. Declaring an instance of Proxy locally inside a never run if statement

    public void myMeth{ if(ProxyIsAvailableWhichItIsNot){ Proxy myInst; ... } }

Update: As pointed out by Henning, I am interested in when a class is initialized (and static blocks run), rather than when it is loaded. I updated the question to reflect this.


A Java implementation has a choice of either loading a class as soon as another class that references it is loaded, or postponing this until it becomes necessary to initialize the class. In the first case, the class can sit around for a considerable amount of time (perhaps forever) being loaded but not initialized.

In contrast, there are precise rules for when a class is initialized (static initializers run), namely the first time an object of the class is created, or a static method called, or a non-constant static field is accessed.

The only completely sure way to prevent a JVM from trying to load a class is not to mention it explicitly in the code and use Class.forName() and reflection to request loading at some definite point in time, at which time ClassNotFoundException may be thrown and handled. However, modern JVMs typically load classes much more lazily than the language specification allows them to, so more optimistic strategies will often work in practice.

The "wrapper class" technique described in your link is not guaranteed to work by Java (see §12.1.2 of the Java Language Specification, 3rd edition), but it's entirely possible that Android/Dalvik gives stronger guarantees of its own.


If youare using the technique listed in that URL, part of the technique involves calling the static method to validate if the class is loadable with the current APIs or not. That allows you to do something like this:

  1. Generate a boolean value, such as IsMyProxyAvailable
  2. Call your static checkAvailable() method on your proxy class
  3. Set the value to true when the method succeeds, false if you except when calling it.

You could also create a singleton factory for this class that handles the above check, and either returns an instantiated class when it's available, or null. It sounds like you are wanting to avoid having to scope around the boolean, which a factory would (sort of) enable you to avoid (with a different cost).


Java has a very defined way classes are loaded. In Java all code is loaded through a ClassLoader. The bytes loaded by the class are kept in memory for the length of the ClassLoader instance therefore, your Class instance will live as long as the ClassLoader instance survives. Classes can't be reloaded or redefined after being loaded without throwing away the ClassLoader that loaded it. When a class is loaded by the ClassLoader it's static initializer blocks are called. Therefore, class loading is basically the same time as Class initialization.

What triggers a class to be loaded? If another class that depends on it is loaded. When the Java compiler is compiling a class it writes into the class file all qualified classnames it depends on. Classes are loaded as late as possible so typically this means when you instantiate them under normal conditions. However, having static members will force those to be loaded prior to this class being loaded. Instance members will be loaded when this class is instantiate as well. If you want lots of good details of this process read the following:

http://www.ibm.com/developerworks/java/library/j-dyn0429/

Fortunately, Dalvik VM works remarkable similar to the JVM because Java specifies this process in great detail.

With you using the Wrapper method in the static initializer if the Class.forName() succeeds it doesn't matter when how you define Proxy (option 1 or 2) because it will already be loaded. Otherwise the parent Wrapper class won't load. So just do option 1 since it's simpler.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜