Java Intricacies

Sequence of Execution

Init blocks execute in the order they appear.
Static initialization blocks are executed at class loading time and they run once.
Instance initialization blocks run after the constructor's call to super().
Instance initialization blocks run every time a class instance is created

Here is a sample to illustrate the behavior:

package com.learn.java;

import java.io.PrintStream;

class SuperClass {
static {
System.out.println("Superclass Static Block");
}

static PrintStream strStatic = System.out.append("Superclass Static Field Init\n");
PrintStream strInst = System.out.append("Superclass Field Init\n");

{
System.out.println("Superclass Instance block");
}

// no-arg constructor
public SuperClass() {
System.out.println("Superclass constructor");
}
}

public class SubClass extends SuperClass {
static {
System.out.println("Subclass Static block");
}

static PrintStream strStatic = System.out.append("Subclass Static Field Init\n");
PrintStream strInst = System.out.append("Subclass Field Init\n");

{
System.out.println("Subclass Instance block");
}

// no-arg constructor
public SubClass() {
System.out.println("Subclass constructor");
}

// main method
public static void main(String[] args) {
new SubClass();
}
}


Output:

Superclass Static Block
Superclass Static Field Init
Subclass Static block
Subclass Static Field Init
Superclass Field Init
Superclass Instance block
Superclass constructor
Subclass Field Init
Subclass Instance block
Subclass constructor

Effects of Inheritance on Serialization

If a superclass is Serializable, then according to normal Java interface rules, all subclasses of that class automatically implement Serializable implicitly.

What happens if a superclass is not marked Serializable, but the subclass is marked Serializable? Can the subclass still be serialized? Will the superclass also be serialized?

In this scenario, when an object is deserialized, then any instance variables you INHERIT from that superclass will be reset to the values they were given during the original construction of the object. In other words, the constructor of the superclass WILL run!

In fact, every constructor of the superclass in the inheritance tree till the first non-serialzable class constructor will run.

If you do not have a constructor with no arguments in any of such classes, then the JVM will throw InvalidClassException!!!

Serialization

Serialization lets you save an object and all of its instance variables.

How do you know if an object is being instantiated or is being deserialized?

You will be able to know this by overriding readObject() and writeObject() methods. Java serialization has two private methods mentioned beforehand that will be invoked automatically during serialization and deserialization. The serialization system’s callback contract makes sure that these methods will be called.

Here are the method signatures:

private void writeObject(ObjectOutputStream os) {

try {
os.defaultWriteObject();

// custom code as part of serialization
...
...
...
} catch (Exception ex) {
// handle exception
}
}

private void readObject(ObjectInputStream is) {

try {
is.defaultReadObject();

// custom code as part of deserialzation
...
...
...
} catch (Exception ex) {
// handle exception
}
}

When a class is deserialized, the constructor of the class does not run, and the instance variables are NOT given their initially assigned values!

Transforming XML data to another format

Here is a quick start tutorial on how to transform XML data to another XML document or any other format.

Main components or actors for achieving this:
  1. XSL Stylesheet
  2. XML document (input data)
  3. JAXP Transform libraries
JAXP stands for Java API for XML Processing. JAXP lets you validate, parse and transform XML using several different APIs. JAXP is vendor neutral and easy to incorporate in to your project.




JAXP’s interpreting implementation of XSLT is Xalan. JAXP’s transformation libraries are found under javax.xml.transform package.

javax.xml.transform:
  • Defines basic set of interfaces for XSLT processors.
  • Defines factory class you use to get a Transformer object.
  • You can configure the transformer with input and output objects, and invoke its transform() method to make the actual transformation.
You can define 3 different types of Source and Result:
  • DOM (javax.xml.transform.dom) – uses DOM.
  • SAX (javax.xml.transform.sax) – uses SAX event generator.
  • Stream (javax.xml.transform.stream) – uses I/O stream.
Code snippet:


try {

TransformerFactory factory = TransformerFactory.newInstance();

// Specify XSL document
Transformer transformer = factory.newTransformer(new StreamSource(xsl-document));

// Specify XML Input
StreamSource xmlsource = new StreamSource(xml-input);

// Specify Target Output
StreamResult output = new StreamResult(System.out);

// Do the magic
transformer.transform(xmlsource, output);

} catch (TransformerException) {
// Handle Exception Code
}

Have you ever wondered where your class file currently loaded by your class loader?

There are instances where you bundle same class file in different jars and distribute it. You may tend to have them in your application’s class path so that it can be loaded by the class loader and referenced at run time. Do you want to know which class file you’re referring to at run time? There are a couple of ways to achieve this:

Using VM parameter: -XX:+TraceClassLoading
Using the following code snippet

        public static URL getClassLocation (final Class cls)
        {
            if (cls == null) throw new IllegalArgumentException ("null input: cls");
          
            URL result = null;
            final String clsAsResource = cls.getName ().replace ('.', '/').concat (".class");
          
            final ProtectionDomain pd = cls.getProtectionDomain ();
            // java.lang.Class contract does not specify if 'pd' can ever be null;
            // it is not the case for Sun's implementations, but guard against null
            // just in case:
            if (pd != null)
            {
                final CodeSource cs = pd.getCodeSource ();
                // 'cs' can be null depending on the classloader behavior:
                if (cs != null) result = cs.getLocation ();
              
                if (result != null)
                {
                    // Convert a code source location into a full class file location
                    // for some common cases:
                    if ("file".equals (result.getProtocol ()))
                    {
                        try
                        {
                            if (result.toExternalForm ().endsWith (".jar") ||
                                result.toExternalForm ().endsWith (".zip"))
                                result = new URL ("jar:".concat (result.toExternalForm ())
                                    .concat("!/").concat (clsAsResource));
                            else if (new File (result.getFile ()).isDirectory ())
                                result = new URL (result, clsAsResource);
                        }
                        catch (MalformedURLException ignore) {}
                    }
                }
            }
          
            if (result == null)
            {
                // Try to find 'cls' definition as a resource; this is not
                // documented to be legal, but Sun's implementations seem to allow this:
                final ClassLoader clsLoader = cls.getClassLoader ();
              
                result = clsLoader != null ?
                    clsLoader.getResource (clsAsResource) :
                    ClassLoader.getSystemResource (clsAsResource);
            }
          
            return result;
        }

Followers