Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Friday, November 22, 2013

Java Virtual Machine - Loading, Linking and Initializing

Loading

  • Process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation.
  • (JVM Specification: ) Java Virtual Machine specification gives implementations flexibility in the timing of class and interface loading.
  • Internal data structures are populated including Method area.
  • An instance of class java.lang.Class for the class being loaded is created.
  • Information about a type that is stored in the internal data structures and accessed by invoking methods on the Class instance for that type.
  • If Class Loader encounters a problem, it is reported during linking phase (LinkageError) on first active use of the class.

Linking 

  • A class or interface is completely loaded before it is linked. 
  • Process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed.
  • Linking a class or interface involves verifying and preparing that class or interface, its direct superclass, its direct superinterfaces.
  • Dynamic linking involves locating classes, interfaces, fields, and methods referred to by symbolic references stored in the constant pool, and replacing the symbolic references with direct references.
  • Linking is divided into three sub-steps: verification, preparation, and resolution:
    • Verification ensures the type is properly formed and fit for use by the Java Virtual Machine.
      • Verification ensures that the binary representation of a class or interface is structurally correct.
      • Verification may cause additional classes and interfaces to be loaded but need not cause them to be verified or prepared.
      • Final classes/methods, abstract classes/methods validations are checked here.
    • Preparation involves allocating memory needed by the type, such as memory for any class variables.
      • Involves creating the static fields for a class or interface and initializing such fields to their default values (initializing to other values except default values is done in Initialization where explicit initializers are executed).
    • Resolution is the process of transforming symbolic references in the constant pool into direct references. 
      • It is an optional part of linking.
      • Implementations may delay the resolution step until each symbolic reference is actually used by the running program.
      • After verification, preparation, and (optionally) resolution are completed, the type is ready for initialization. Resolution, which may optionally take place after initialization.
  • (JVM Specification: ) Java Virtual Machine specification gives implementations flexibility in the timing of class and interface linking.

Initialization

  • Initialization of a class or interface consists of executing the class or interface initialization method <clinit>.
    • <clinit> is static and has no arguments and is for static initialization blocks.
    • If there is no initialization of class variables in the code, compiler will not generate <clinit> method
  • Class variables are initialized during Initialization phase.
  • Initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time.
  • (JVM Specification: ) All implementations must initialize each class and interface on its first active use.
  • Involves creating the static fields for a class or interface and initializing such fields to their default values (initializing to other values except default values is done in Initialization where explicit initializers are executed).

Class-In-Use (Working with Objects)

  • For each constructor in the source code of a class, the Java compiler generates one <init() method.
  • If the class declares no constructors explicitly, the compiler generates a default no-arg constructor that just invokes the superclassís no-arg constructor.
  • For every class except Object, an <init() method must begin with an invocation of another <init() method belonging either to the same class or to the direct superclass.
  • Instance initialization methods may be invoked only by the invokespecial instruction (§invokespecial), and only on uninitialized class instances.

Unloading Class

  • Java Virtual Machine will run a class's classFinalize() method (if the class declares one) before it unloads the class.
  • If the application has no references to the type, then the type can't affect the execution of program and it can be garbage collected.

Class Loader

  • At run time, a class or interface is determined by a its binary name and defining class loader both.
  • Class Loader deals with file system to load the files for the JVM, no other component in JVM needs to deal with file system.
  • All Java virtual machines include one class loader that is embedded in the virtual machine, called Primordial class loader.
  • Every Class object contains a reference to the ClassLoader that defined it.
    • Class.getClassLoader()
  • Class LoaderTestClass loaded by class loader A, is not the same class as the class LoaderTestClass loaded with class loader B.
  • There are following three types of class loaders:
    • Bootstrap Class Loader
    • System Class Loader
    • Extension Class Loader

Premordial (Bootstrap) Class Loader

  • It implements the default implementation of loadClass().
  • Written in native language.
  • JVM assumes that it has access to a repository of trusted classes which can be run by the VM without verification.
  • Java core API classes are loaded by the bootstrap (or primordial) Class Loader.
  • Bootstrap ClassLoader searches in the locations (directories and zip/jar files) specified in the sun.boot.class.path system property.
    • String bootClassPath = System.getProperty("sun.boot.class.path");
  • Types loaded through the primordial class loader will always be reachable and never be unloaded.

Application (System) Class Loader

  • Application-specific classes are loaded by the system (or application) ClassLoaders.
  • Our application's code is loaded using this.
  • The system ClassLoader searches for classes in the locations specified by the classpath (set as the java.class.path system property) command-line variable passed in when a JVM starts executing. 
    • String appClassPath = System.getProperty("java.class.path");
    • sun.misc.Launcher$AppClassLoader

Extensions Class Loader

  •  Loads the code in the extensions directories (<JAVA_HOME>/jre/lib/ext, or any other directory specified by the java.ext.dirs system property).
    • String extClassPath = System.getProperty("java.ext.dirs");
    • sun.misc.Launcher$ExtClassLoader

Custom (User-Defined) Class Loader

  • Subclass of the abstract class Java.lang.ClassLoader. 
  • Method loadClass is to be implemented.
    • loadClass should be synchronized.
    • Call findLoadedClass to check class is already loaded. 
    • If we have the raw bytes, call defineClass to turn them into a Class object.
    • If the resolve parameter is true, call resolveClass to resolve the Class object.
    • If class not found, throw a ClassNotFoundException.
  • Every loaded class needs to be linked. This is done using the ClassLoader.resolve() method. This method is final.
  • Following are the steps a class loader performs:
    • Check if the class was already loaded.
    • If not loaded, ask parent class loader to load the class. 
    • If parent class loader cannot load class, attempt to load it in this class loader.

Examples of Class Loaders:

  • java.net.URLClassLoader, 
  • java.security.SecureClassLoader

Related Terms and Concepts:

JVM Startup

  • The Java Virtual Machine starts up by creating an initial class, which is specified in an implementation-dependent manner, using the bootstrap class loader.
  • The Java Virtual Machine then links the initial class, initializes it, and invokes the public class method void main(String[]). 
  • In an implementation of the Java Virtual Machine, the initial class could be provided as a command line argument. Alternatively, the implementation could provide an initial class that sets up a class loader which in turn loads an application. 

JVM Dynamic Linking

  • The process of JVM loading your program's classes and interfaces and hooking them together.
  • Java Virtual Machine builds an internal web of interconnected classes and interfaces.

Binding

  • Binding is the process by which a function written in a language other than the Java programming language and implementing a native method is integrated into the Java Virtual Machine so that it can be executed.
  • Although this process is traditionally referred to as linking, the term binding is used in the specification to avoid confusion with linking of classes or interfaces by the Java Virtual Machine. 
Previous: Java Virtual Machine - Garbage Collection

Tuesday, November 12, 2013

Java Virtual Machine - Garbage Collection


  • Garbage Collection is not restricted to Java, its a generic concept that applies to most of the programming languages.
  • Garbage collection is the process of automatically freeing objects that are no longer referenced by the program. 
  • The garbage collector must determine which objects are no longer being referenced by the program.
  • Garbage collector must run any finalizers of objects being freed.
  • Garbage collection is automatic, thus it removes the possibility of developer errors due to incorrectly freeing of memory.
  • Runtime.gc() and System.gc() only suggests JVM to run Garbage Collection, it is not mandatory that Garbage Collection will definitely run after call to these methods.
  • Java virtual machine has an instruction that allocates memory on the heap for a new object (created in source coce), but has no instruction for freeing that memory.
  • Garbage Collection in Java is carried by JVM's  daemon threads for Garbage Collection.
  • Garbage collection was invented by John McCarthy around 1959 to solve problems in Lisp.

Java provides many garbage collectors, following are some examples:

  • Parallel Scavenge
  • Serial Garbage Collector
  • Parallel New + Serial GC
  • CMS (Concurrent Mark and Sweep)
  • G1 (Garbage First, available in Java7)

Regarding JVM Specification:

  • JVM specification does not specify any particular garbage collection technique, the decision to choose the garbage collection algorithm is left to the discretion of the implementors as they better know the constraints of the target device.
  • JVM specification mentions the need of garbage collection on heap, it leaves garbage collection or compacting the method area on implementers.
  • A garbage collector is not strictly required but heap memory should be managed.
  • The Java language specification states that a finalizer code will be executed only once. Finalizer are allowed to "resurrect" the object again, that is it'll be referenced again, but finalizer will not run next time.

Additional Responsibilities:

  • Heap Defragmentation

Disadvantages:

  • Developer has no control on Garbage Collection, reducing the use the finalizers.
  • At times, it may lead to uneven performance of the application components, as we don't know when Garbage collection will run and how much resources and time it'll consume.

Steps:

  • Garbage Detection
    • Identification of live and garbage objects.
    • Objects on heap which don't have any active references are available for garbage collection.
    • This process is also called Marking.
  • Reclaim Memory
    • Removes unreferenced objects leaving referenced objects and pointers to free space.
  • Optional Step: Compacting
    • Defragments the memory space, compacts the remaining referenced objects. This makes new memory allocation much easier and faster.

Stop the World Pauses:

  • Stop-the-world is term for JVM stopping the application (all threads) from running to execute a GC.
  • The interrupted tasks will resume only after the GC task has completed. 
  • GC tuning often means reducing this stop-the-world time.

Disruptive Garbage Collection vs Deterministic Garbage Collection:

  • Garbage collection with noticable Stop the World pauses are called Disruptive Garbage collection.
  • Disadvantages - These are not suitable for Real-time systems. For end-users noticable pauses are irritating.
  • Solution Approach - Garbage collection should work incrementally, on small areas of heap at a time.
    • If each incremental collection can be completed in < Threashhold time, then it is suitable for Real-time system.
    • Example - Generational Collector used in Hotspot JVM, discussed below.

Tracing Garbage Collector:

  • Tracing garbage collectors are the most common type of garbage collector. They first determine which objects are reachable (or potentially reachable), and then discard all remaining objects.

Syntactic vs Semantic Garbage:

  •  The reachability definition of "garbage" is not optimal, as there are two cases.
    • CASE #1: An object variable is now reassigned thus original object doesn't have any references left.
    • CASE #2: An object is still available in the program, but it is not used anymore.
  • Syntactic Garbage (Objects that a program cannot possibly reach)
    • It'll handle CASE #1 but not CASE #2.
  • Semantic Garbage (Objects that a program will never use again)
    • It'll handle CASE #1 and CASE #2 both.

Weak vs Strong References:

  • An object is eligible for garbage collection if there are no strong (i.e. ordinary) references to it, even though there still might be some weak references to it.
  • Weak Reference is usually reserved for a properly managed category of special reference objects which are safe to use even after the object disappears because they lapse to a safe value.
  • Weak References will be discussed in another post soon.

Precise vs Conservative:

  • Collectors that correctly identify all references to an object are called precise (also exact or accurate) collectors.
  • Collectors that don't identify all references to an object correctly are called conservative or partly conservative collector.
  • Conservative garbage collectors have traditionally been used in conjunction with programming languages like C and C++, which were not originally designed with a garbage collector in mind.
  • Conservative collectors assume that any bit pattern in memory could be a pointer if, interpreted as a pointer, it would point into an allocated object.

Moving (Compacting) vs Non-Moving (Non-compacting) Garbage Collectors

  • A moving GC strategy appears costly and low performance but it gives better performance. Following are details on this:
    • Since memory is defragmented, large contigous memory is available, new objects can be allocated very quickly.
    • No additional work is required to reclaim the space freed by dead objects; the entire region of memory from which reachable objects were moved can be considered free space.
    • While moving the objects special care is needed for objects passed to native methods, as there might be native pointers pointing to this.
  • Updating references after moving objects is made simpler by adding another layer of abstraction in between. Object references will point to a table of object handles and not directly refer to objects. Thus after de-fragmentation, only the object handle table will get updated.

Garbage Detection:

  • An object becomes eligible for garbage collection if its all references are null, i.e. If its not reachable from any live threads or any static references.
  • Achieved by defining a set of roots and determining reachability from the roots.
  • A distinguished set of objects are assumed to be reachable: these are known as the roots.
  • Typically, set of roots include all the objects referenced from anywhere in the call stack, and any global variables.
    • Object references in Local variables and 
    • Operand stack frame, 
    • Static members of classes in method area, 
    • Object references passed to currently executing native methods, etc.
  • An object is reachable if there is some path of references from the roots by which the executing program can access the object. Reachability is a transitive closure.
  • The roots are always accessible to the program. Any objects that are reachable from the roots are considered live. 
  • Objects that are not reachable are considered garbage.
  • Cyclic dependencies are also taken care this way.

Approaches for Garbage Detection:

  • Tracing
    • Trace the references from roots.
    • Mark and Swipe is basic Tracing Collector.
  • Reference Counting
    • Keeps count of the references to an object.
    • Advantage - It can run in small chunks of time closely interwoven with the execution of the program. This characteristic makes it particularly suitable for real-time environments where the program can't be interrupted for very long.
    • Disadvantage - It does not detect cycles: two or more objects that refer to one another.
    • This technique is currently out of favor.

Approaches for Heap Fragmentation Problem:

  • Compacting Collector
    • Slide/Move live objects to defragment the heap area.
    • Examples:
      • Mark and Swipe
      • Tri-color Marking
  • Copying Collector
    • Copying garbage collectors move all live objects to a new area.
    • Examples:
      • Stop-and-Copy

Generational Garbage Collection

  • The generational collection technique can be applied to mark and sweep algorithms as well as copying algorithms.
  • Dividing the heap into generations of objects can help improve the efficiency of the basic underlying garbage collection algorithm.
  • The most recently created objects are most likely to become unreachable quickly (known as infant mortality or the generational hypothesis).
  • Heap is divided into two or more sub-heaps, each of which serves one "generation" of objects.
  • The younger generation is garbage collected more frequently than older generation. 
  • Once an object has survived a few garbage collections as a member of the youngest generation, the object is promoted to the next generation: it is moved to another sub-heap.
  • Every sub-heap except the mature sub-heap can be given a maximum size.
  • Any objects that don't fit in the sub-heaps of the younger generations must go into the mature object space, thus mature object space cannot be given a maximum size.
  • It ensures that most incremental GC will be complete in less than a threshhold time. Only exception is Mature Generation.
  • Following image shows generational garbage collection in Hotspot JVM:

Train Algorithm:

  • Specifies an organization for the mature object space of a generational collector for time bound incremental collections of the mature object space.
  • The train algorithm, which was first proposed by Richard Hudson and Eliot Moss and is currently used by Sun's Hotspot virtual machine.
  • Divides the mature object space into fixed-sized blocks of memory, each of which is collected individually during a separate invocation of the algorithm.
    • Each block belongs to one set. 
    • The blocks within a set are ordered, and the sets themselves are ordered. 
  • Small number indicate an older block within a set and Set with the heap.
  • For more details on this alogorithm, please google or refer to references section at the end of the Blog post.


Types of Garbage Collectors (Garbage Collection Approaches/Strategies/Algorithms)

  • Stop-and-Copy (Semi-space) Collector
    • Memory is partitioned into a "from space" and "to space". 
    • Initially, objects are allocated into "to space" until they become full and a collection is triggered. 
    • At the start of a collection, the "to space" becomes the "from space", and vice versa. 
    • The objects reachable from the root set are copied from the "from space" to the "to space". 
  • Mark and Sweep
    • This is an example of tracing collector.
    • Each object in memory has a flag (typically a single bit) reserved for garbage collection use only.
    • In Garbage detection, every object that is ultimately pointed to from the root set is marked.
    • In Memory Reclaim step, entire memory is scanned, all non-reachable objects are freed.
    • Disadvantage - Entire system must be suspended during garbage collection; no mutation of the working set can be allowed. This will cause programs to 'freeze' periodically (and generally unpredictab'ly), making real-time and time-critical applications impossible.
  • Tri-Color Marking:
    • This is an example of tracing collector.
    • White-Set (Condemned Set)
      • Objects that are candidates for having their memory recycled.
    • Black-Set
      • Objects that can cheaply be proven to have no references to objects in the white set, but are also not chosen to be candidates for recycling; in many implementations, the black set starts off empty.
      • In many implementations, the black set starts off empty.
    •  Grey-Set
      • Objects that are reachable from root references but the objects referenced by grey objects haven't been scanned yet. 
      • The grey state means we still need to check any objects that the object references.
      • Grey objects will eventually end up in the black set.
    •  The grey set is initialised to objects which are referenced directly at root level; typically all other objects are initially placed in the white set.
    • Objects can move from white to grey to black, never in the other direction.
    • Advantage: it can be performed 'on-the-fly'.
  • Mark and Don't sweep
    • This is an example of tracing collector.
    • All reachable objects are always black.
    • A white object is unused memory and may be allocated.
    • The interpretation of the black/white bit can change. Initially, the black/white bit may have the sense of (0=white, 1=black).
    • If an allocation operation ever fails to find any available memory, the sense of the black/white bit is then inverted (0=black, 1=white). Thus all objects become white. A marking phase begins immediatly to mark reachable objects black.

Adaptive Collectors

  • An adaptive algorithm monitors the current situation on the heap and adjusts its garbage collection algorithm and configuration.

Oracle Java 7 G1 (Garbage First) Garbage Collector:

  • Compact free space without lengthy and more predictable GC induced pause times.
  • Its still not suitable for Real-Time systems.
  • Targetted for multi-processors with large memories.
  • G1 is both concurrent and parallel. 
    • It uses all available CPUs to speed up its “stop-the-world” pauses. 
    • It also works concurrently with running Java threads to minimize whole-heap operations during stop-the-world pauses.

Monday, November 4, 2013

Java Virtual Machine - Introduction

Typical Java Environment consists of following:
  •  Java Programming Language
    • JDK
    • Source code is in Java.
  • Java Class File Format
    • Bytecode
  • Java API
    • Standard classes and interfaces of JDK.
  • JVM
    • Java Virtual Machine

JVM:

  • The Java Virtual Machine, or JVM, is code executing component of Java platform.
  • Abstract machine that runs compiled Java programs.
  • The JVM is "virtual" because it is implemented in software on top of a "real" hardware platform and operating system.
  • The Java Virtual Machine is an abstract computing machine. Like a real computing machine, it has an instruction set and manipulates various memory areas at run time. 
  • Oracle JVM specifications specifies an abstract machine, it doesn't describe any particular implementation of JVM.
  • Java is for platform-independence, each Java platform has different constraints. Java specification doesn’t give hard and fast rules about the design of JVM with respect to memory and other aspects. JVM is implemented specifically for each platform, and implementation of JVM is left to jvm implementers.

Role:

  • Read the Class file format (Bytecode) and correctly performs the operations specified in it.

Key points:

  • Any implementation details like memory structures, garbage-collection etc are not part of the Java Virtual Machine's specification would unnecessarily constrain the creativity of implementers.
  • The Java Virtual Machine knows nothing of the Java programming language, it only cares for Virtual Machine instructions (or bytecodes).
  • All Java Virtual Machine implementations must recognize the Java class file format, but individual implementations may also recognize other binary formats.
  • Any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java Virtual Machine.
  • For the sake of security, the Java Virtual Machine imposes strong syntactic and structural constraints on the code in a class file for security concerns.

Advantages:  

  • Hardware and operating system independence. 
  • Small size of its compiled code. 
  • Protect users from malicious programs. 
    • Bytecode is carefully inspected by JVM before execution.

JVM Implementation:

  • Like most virtual machines, the Java virtual machine machine has a stack-based architecture akin to a microcontroller/microprocessor. 
  • JVM doesn't have registers for storing arbitrary values. All computation in the JVM centers on the stack, everything must be pushed onto the stack before it can be used in a calculation.
  • JVM are usually coded for a particular OS but it can also be coded directly on hardware.
  • JVM also has low level support for Java like classes and methods, which amounts to a highly idiosyncratic memory model and capability-based architecture.
  • JVM has no built-in support for dynamically typed languages.
  • JVM supports following 7 primitive types:
    • byte     -    one-byte signed two's complement integer
    • short    -    two-byte signed two's complement integer
    • int        -    4-byte signed two's complement integer
    • long     -    8-b yte signed two's complement integer
    • float     -    4-byte IEEE 754 single-precision float
    • double -    8-byte IEEE 754 double-precision float
    • char     -    2-byte unsigned Unicode character
  • Few Examples:
    • Most popular JVM implementation is from Oracle and is named HotSpot, written in C++.
    • Jinitiator is another popular JVM implementation, especially in Oracle Apps community, developed by Oracle for supporting forms on websites before they purchased Sun. 
    • Mac OS Runtime for Java (MRJ, originally Macintosh Runtime for Java).
    • SAPJVM (SAP) is a licensed and modified SUN JVM ported to all supported platforms of SAP NetWeaver

About Bytecode

  • Machine language of the Java virtual machine.
  • Each instruction consists of a one-byte opcode(represents operation) followed by zero or more operands.
  • An opcode may optionally be followed by operands(represents parameters required by opcodes).
  • The total number of opcodes is less (~200), each opcodes requires only one byte. 
    • This helps in minimizing the size of class files and JVM implementation.
  • Java Bytecode is an intermediate language which is typically compiled from Java but it can also be compiled from other programming language, ex ADA.
  • Class files contain bytecode and a symbol table, as well as other ancillary information.
  • Any language with functionality that can be expressed in terms of a valid class file can be hosted by the Java Virtual Machine.
  • JVM has instructions for Load/Store of variables, Arithmetic, Type Conversions, Stack Management, Exception management, and Monitor based concurrency control etc.
  • Examples of Opcodes:
    • iload, lload, fload, and dload  are used to load int, long, float and double operand on the stack respectively.
    • istore, fstore are used to pop int and float from the stack to a variable.
    • aload, astore operates on references.
  • There is no support for loops and binary logical operators (|| &&). These are implemented by compiler with jump instructions.

Class File

  • Each class file contains the definition of a single class or interface. 
  • A class file consists of a stream of 8-bit bytes. All 16-bit, 32-bit, and 64-bit quantities are constructed by reading in two, four, and eight consecutive 8-bit bytes, respectively. 
  • Multibyte data items are always stored in big-endian.

Execution Engine:

  • It consists of following:
    • Bytecode Interpreter
    • JIT (Just In Time) Compiler
      • Since byte code is interpreted it executes slower than compiled machine code.
      • Just-in-time compilation (JIT) is also known as dynamic translation.
      • JIT is used to improve the runtime performance of byte code.
      • The program is stored in memory as byte code, but the code segment currently running is preparatively compiled to physical machine code in order to run faster.
    • Virtual Processor

JRE:

  • Java Execution Environment (Java Runtime Environment). 
  • JRE contained JVM and java class libraries that implement java API.

Other JVM Languages

  • Groovy
  • Scala
  • Jython
  • JRuby
  • Kotlin

Wednesday, October 2, 2013

NESTED CLASSES - Static Nested and Inner Classes

Nested Class:

  • Introduced in version 1.1 of Java.
  • Class within another Class.
  • A nested class is a class whose definition appears inside the definition of another class, as if it were a member of the enclosing class.
  • A nested class can be declared private, public, protected, or package private. 
  • Nested class can be hidden from all other classes using 'private' modifier.
  • Nested Classes are compiled as separate class files with following format:
    • EnclosingClass$InnerClass.class
    • EnclosingClass$StaticNestedClass.class
  • To run main method of nested class, use "java EnclosingClass$StaticNestedClass".
  • Divided into two categories - static and non-static (Inner Classes)
  • Nested class may be nested within another Nested class.
      

      class EnclosingClass {
          ...
          static class StaticNestedClass {
              ...
          }
          class InnerClass {
              ...
          }
      }

Features of Nested Classes:

  • Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.
  • Static nested classes do not have access to other members of the enclosing class.
  • Inner class is associated with an instance of enclosing instance.
  • A static nested class is associated with enclosing class(not object).
  • The way static methods cannot access non static members, static nested class cannot refer to non-static members without object reference. 
  • Inner Class can access non-static members.
  • Inner class cannot have static members (except constants) because it is linked to an instance of enclosing class.
  • A static nested class is same as any top-level class just that it has been packaged in another top-level class. Only difference is static nested class can access private static members.
  • Inner class instance knows about the enclosing class instance, it can access its members using "<EnclosingClassName>.this".
        this.<member-name> // Inner Class's member
        <EnclosingClassName>.this.<member-name>  // Enclosing Class's member
  • Static nested classes are known as nested top-level classes.
  • An enclosing class can have multiple inner classes extending other classes, thus providing a way to achieve multiple inheritence.
  • Inner class needn't be created at the time of creation of enclosing class, it can be created any time after that.
  • An enclosing class can have multiple instances of same inner class, each with its own state. (Ex. multiple iterators for a rowset).

Typical Usage:

Inner class extends another class or implements an interface (ex. java.util.Iterator). Inner class can access outer class members and closely perform operations on them.
Used for writing test cases, since nested classes have access to private members.
Inner classes are best used in the event handling mechanism and to implement the helper classes.

Why we need Inner Classes:

In the above example, if Iterator would have been a class and not interface, then design couldn't have survived without Inner class, because a class can only extend one class (in that case only Iterator).

Miscellaneous Facts on Nested Classes:

  • Java supports the concept of nested classes in interfaces, though its a teriible programming practice. Following code will compile:
    public interface EnclosingInterface {
        void testMethod();
        class InnerClass {
            int x = 10;
            public void testx() {
                System.out.println(x);
            }
        }
    }
  • Java supports nested interfaces within interfaces but its also a bad programming practice.
  • Java supports nested interfaces within classes, though they are helpful in rare scenarios. These also can be avoided with the use of top-level interfaces.

Local Classes

  • Local classes are classes that are defined in a block, typically inside a method body, though it can be within a loop, if-else blocks etc.
  • Local classes (since its Inner Class) are non-static because they have access to instance members of the enclosing block.
  • A local class (since its Inner Class) has access to the members of its enclosing class.
  • Local classes (since its Inner Class) they cannot define or declare any static members or initializers except constants.
  • Local classes defined in static methods, can only refer to static members of the enclosing class.
  • A local class has access to final local variables as well.
  • local class names are in this format:
    • <EnclosingFormat>$<number><LocalClassName>.class
    • <number> starts with 1, gets incremented by 1 and so on. <number> is coming here because class names can be repeated in different blocks.
    • Ex. EnclosingClass$1LocalA.class, EnclosingClass$1LocalB.class

Anonymous Classes

  • They are like local classes except that they do not have a name.
  • Use them if you need to use a local class only once.
  • They enable you to declare and instantiate a class at the same time. 
  • It is an abbreviated notation for creating a simple local object "in-line" within any expression, simply by wrapping the desired code in a "new" expression.
  • While local classes are class declarations, anonymous classes are like expressions.
  • Anonymous class must be part of a statement since its like an expression.
  • Anonymous classes enable you to make your code more concise.
  • The syntax of an anonymous class expression is like the invocation of a constructor, except that there is a class definition contained in a block of code.
  • Anonymous classes have the same access to local variables of the enclosing scope as local class.
  • Anonymous classes also have the same restrictions as local classes with respect to their members
  • you cannot declare constructors in an anonymous class.
  • Since anonymous classes have no names, the Java compiler uses numbers to provide anonymous class names. Ex. EnclosingClass$1.class.
  • The anonymous class expression consists of the following:
    • The new operator
    • The name of an interface to implement or a class to extend.
    • Parentheses that contain the arguments to a constructor. In case of implementing an interface, there shouldn't be any parameters.
    • Body of class. Method declarations are allowed in body but statements are not. 
  • Syntax:
    new class-name ( [ argument-list ] ) { class-body }
    or:
    new interface-name () { class-body }
    // No argument list with interface.
  • These are mostly used in event handling.
  • They are useful for writing small encapsulated "callbacks," such as enumerations, iterators, visitors, etc.
  • Like local classes, anonymous classes cannot be public, private, protected, or static.  

When to use Member, Local and Anonymous classes?

  • When to use anonymous classes and when to use local classes depends on number of instances needed. If number of instances are more, its local class.
  • When to use local classs and when to use member class depend on the availability of the new type. If wide availability is needed, its member class.

How Inner Classes are Implemented in JVM?

  • Inner classes were introduced in Java 1.1.
  • Introduction of inner classes did not change the Java Virtual Machine or the Java class file format.
  • For Java interpreter and JVM all classes are normal top-level classes.
  • Java compiler inserts hidden fields, methods (getters for instance references), and constructor arguments into the classes it generates. 

Java 8 Enhancements:

  • Local class can access local variables effectively final (whose value is never changed after initialization).
  • Local class can access parameters of the enclosing block, i.e., method parameters in case Local class is defined in a method.

Saturday, September 28, 2013

Java Annotations - An Overview

Introduction

  • Introduced in JDK 1.5
  • One of the biggest ever feature added in Java.
  • A form of syntactic metadata that can be added to Java source code. Its basically Data about Data.
  • Annotations don't do anything on their own, they don't do any processing. They act like a modifier and become useful only when they are processed.
  • Annotations can be processed at compile time, run time or deployment time.
  • Annotations are tags that we insert into our code, to be processed by tools like compiler, deployment tools or other external packages. Annotations are part of the code.
  • Can be embedded in class files generated by the compiler and may be retained by the Java VM to be made retrievable at run-time.(Reference: Retention policy)
  • Prior to Annotations, Java provided only ad-hoc and non-standardized mechanism, including Serializable interface (other market interfaces), transient modifier, Javadoc comments, @deprecated tag in comments.One of the main reasons for adding annotation and metadata to the Java platform is to enable development and runtime tools to have a common infrastructure.
  • Annotations are part of java code, Java Docs are not. 
  • java.lang.annotations package provides library support for the Java programming language annotation facility.
  • Normally a developer needn't create Annotations.
  • Annotation-based programming is an extensible mechanism for generating application artifacts, packaging the application, and readying the application for execution.
  • Annotation-based programming offers a set of tags and a processing mechanism that allow you to embed additional metadata into code. Application then uses this additional metadata to derive the artifacts required to execute the application in a J2EE environment.

Defining Annotations:

     public @interface TestAnno
     {
        String str(); // It can never has any parameters.
        int count();
     } 

Implementation Key points:

  • @interface keyword is used to define annotations.
  • Annotation types are a form of interface.
  • Annotation elements must be compile time constant values.
  • There is no restriction of the type of annotation element.
  • All annotations consist solely of method declarations. These method declarations are called elements.
  • The declarations must not have any formal parameters or a throw clause.
  • java.lang.annotation.Annotation is super-interface for all annotations.
  • Annotations cannot include the extends clause.
  • Annotations can be applied to any declaration, ex. classes, methods, fields, parameters, enum, constants or even an annotation type.
  • There is a default value element in the annotations.
  • Annotations cannot use Generics, no generic member type, no type parameters.
     public class TestClass
     {
        @TestAnno (str="MyFirstAnnoTest", count=1001) 

        // When a element is given a value only name is used, 
        // paranthesis are not used.
        public static void main(String[] args)
        {
                ...
        }
     } 

  • If the annotation has no elements, then the parentheses can be omitted. Ex @Override.
  • If there is just one element named value, then the name can be omitted. Ex
    • @SuppressWarnings(value = "unchecked")
    • @SuppressWarnings("unchecked")
  • It is also possible to use multiple annotations on the same declaration: 
    • @TestAnno (str="MyFirstAnnoTest", count=1001)      
      @SuppressWarnings("unchecked")
      class  TestClass  { ... }
       

Annotation Uses:

  • Annotations helps moving away redundant code, remove config xml (ex. deployment descriptor), adds extra checks (ex. @override).
  • Provide information to Compiler - 
    • To detect errors or suppress warnings (@Deprecated, @Override, @SuppressWarning)
  • Compile-time and deployment-time processing -
    • Software tools can process annotation information to generate code, XML files, and so forth. Ex @WebServlet, @WebInitParam, @WebFilter, @WebListener etc.
  • Runtime processing - 
    • Marker Annotations

Default Value for Annotation elements

  • We can provide default values to annotations, that will be assigned if no value is specified.
  • A default value is specified by adding a default clause to a member's declaration.
  • Syntax:
    • type member() default default-value
    • default-value must be type compatible with member type.
       public @interface TestAnno
       {
          String str() default "testString" ; 

          int count() default -1 ;
       } 

Marker Annotations

  • Similar in concept with Marker interface - no member methods with sole purpose of marking a declaration.

Single-Member Annotations

  • As the name suggests, only one annotation contains only one member. 
  • member name should be value.
  • Uniqueness - allows to use shorthand, no need to specify the name of the member.
    public @interface TestSingleAnno
    {
       String value() ;

    }
    @TestSingleAnno("Testing Single Annotation")
    public static void main(Sting[] args)
    {
        ...
    }

Java SE Predefined Annotations:

  • @Deprecated
    • Defined in java.lang package.
    • Introduced in Java 1.5
    • When @Deprecated is used, documentation (javadoc @deprecated comment) should reflect why open is deprecated and what to use instead.
  • @Override
    • Defined in java.lang package. 
    • Introduced in Java 1.5  
    • If a method marked with @Override fails to correctly override a method, the compiler throws an error.
    • It helps to prevent errors. 
  • @SuppressWarning 
    • Defined in java.lang package. 
    • Introduced in Java 1.5  
    • Instructs the compiler to suppress specific warnings that it would otherwise generate.
    • Warnings like unused variables, deprecated methods will be suppressed by compiler. 
    • Ex. @SuppressWarnings("deprecation")
    • Ex. @SuppressWarnings({"unchecked", "deprecation"})
  • @SafeVarargs
    • Defined in java.lang package.
    • Introduced in Java 1.7
    • It asserts that the code does not perform potentially unsafe operations on its varargs parameter. 
    • Unchecked warnings relating to varargs usage are suppressed.
  • @FunctionalInterface
    • Defined in java.lang package.
    • Introduced in Java 1.8
    • An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.
    • Conceptually, a functional interface has exactly one abstract method.
    • However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.
    • If a type is annotated with this annotation type, compilers are required to generate an error message unless:
      • The type is an interface type and not an annotation type, enum, or class.
      • The annotated type satisfies the requirements of a functional interface.

Meta-Annotations

Annotations that apply to other annotations.
It is information about annotation.There are several meta-annotation types defined in java.lang.annotati
  • @Retention 
    • Specifies how the marked annotation is stored, at what point, its discarded.
    • Java defines 3 such policies encapsulated in java.lang.annotation.RetentionPolicy enumeration - SOURCE, CLASS, RUNTIME.
    • SOURCE - Retained only in source file and discarded during compilation.
    • CLASS - Stored in .class file during compilation, but its not available through JVM during runtime.
    • RUNTIME - Stored in .class file during compilation, and available through JVM during runtime. It offers the greatest annotation persistence.
    • Default Retention level is CLASS. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS
    • Ex. @Retention(RetentionPolicy.RUNTIME) 
  • @Documented
    • Indicates whenever the specified annotation is used those elements should be documented using the Javadoc tool. 
    • By default, annotations are not included in Javadoc.
    • To make the information in @TestAnno appear in Javadoc-generated documentation, you must annotate the @TestAnno definition with the @Documented annotation:
        // import this to use @Documented
        import java.lang.annotation.*;

        @Documented
        public @interface TestAnno 
        { 
           String str(); // It can never has any parameters. 
           int count(); 
        }

  • @Target
    • Indicates the kinds of program element to which an annotation type is applicable.
    • If a Target meta-annotation is not present on an annotation type declaration, the declared type may be used on any program element.
    • A target annotation specifies one of the following element types as its value:
      • ElementType.ANNOTATION_TYPE can be applied to an annotation type.
      • ElementType.CONSTRUCTOR can be applied to a constructor.
      • ElementType.FIELD can be applied to a field or property.
      • ElementType.LOCAL_VARIABLE can be applied to a local variable.
      • ElementType.METHOD can be applied to a method-level annotation.
      • ElementType.PACKAGE can be applied to a package declaration.
      • ElementType.PARAMETER can be applied to the parameters of a method.
      • ElementType.TYPE can be applied to any element of a class.
       Ex. @Target({ElementType.FIELD, ElementType.METHOD, 
                    ElementType.FIELD})           

           public @interface TestAnno {
            ...

           }
 

           @Target(ElementType.ANNOTATION_TYPE)
           public @interface TestAnno {
            ...
   
       }
  •  @Inherited
    • Indicates that the annotation type is automatically inherited from the super class.
    • This annotation applies only to class declarations.
    • By Default a class doesn't inherit annotations of its super class.
    • When the user queries the annotation type and the class has no annotation for this type, the class' superclass is queried for the annotation type.

Java 8 Enhancements

Type Annotations and Pluggable Type Systems

  • Before the Java SE 8 release, annotations could only be applied to declarations.
  • As of the Java SE 8 release, annotations can also be applied to any type use.
  • A few examples of where types are used are class instance creation expressions (new), casts, implements clauses, and throws clauses.
  • This form of annotation is called a type annotation, following are few examples:
    new @Interned MyObject(); //Class instance creation 

    myString = (@NonNull String) str; //Type cast 

    @NonNull String str;  

    class UnmodifiableList<T> implements
   
    @Readonly List<@Readonly T> { ... } //implements clause 


    void monitorTemperature() throws
         @Critical TemperatureException { ... } //Thrown exception declaration

  • Type annotations were created to support improved analysis of Java programs way of ensuring stronger type checking. 
  • The Java SE 8 release does not provide a type checking framework. 
  • It allows you to write (or download) a type checking framework that is implemented as one or more pluggable modules that are used in conjunction with the Java compiler.

@Repeatable

  • Indicates that the marked annotation can be applied more than once to the same declaration or type use.
  •  There are situations where you want to apply same annotation multiple times to a declaration or type use. Following are few examples:
    • A Project could fall under several project categories.
    • A process needs to be scheduled for multiple time.
    • An event could be observed by multiple roles.
    //custom annotation without repeatable
    public @interface Schedule { ... }
 

    //container annotation for repeatable
    public @interface Schedules {
         Schedule[] value;
    }
 

    //custom annotation with repeatable
    //The value of @Repeatable meta-annotation is container annotation.
    @Repeatable(Schedules.class)
    public @interface Schedule { ... }

Saturday, August 31, 2013

Java - Confusing Terms

Iterable vs Iterator

Implementing Iterable allows an object to be the target of the "foreach" statement. It is in java.lang package. It has one method - Iterator<T> iterator().
Iterator represents iterator over a collection. It is in java.util package. It has three methods - hasNext, Next and remove.

Collection vs Collections

Collection is the root interface in the collection hierarchy. It is in package java.util. This interface is typically used to pass collections around and manipulate them where maximum generality is desired. It implements java.util.Iterable.
Collections class consists exclusively of static methods that operate on or return collections. It doesn't extend/implement any class/interface from collections hierarchy.


Comparator vs Comparable

Comparable interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering, and the class's compareTo method is referred to as its natural comparison method. Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator.
Comparable has int compareTo(T o) method. It is in java.lang package.


A comparator object (a class that implements Comparator interface) can compare any two objects and these two objects are passed as parameters to compare() method.

Comparator is used to sort objects in other than its natural ordering.
Comparator has int compare(T o1, T o2) and equals method. It is in java.util package.
 

Following is the result of the compare methods:
    a) A positive integer value if obj1 is greater than obj2.
    b) 0 value if obj1 and obj2 are equal.
    c) A negative integer value if obj1 is less than obj2.



Hashmap vs Hashtable

  • HashMap is non-synchronized whereas Hashtable is synchronized.
  • Java 5 introduced ConcurrentHashMap which is an alternative of Hashtable and provides better scalability than Hashtable in Java.
  • HashMap allows null values as key and value whereas Hashtable doesn’t allow nulls
  • HashMap does not guarantee that the order of the map will remain constant over time.
  • HashMap can be synchronized by:
    • Map m = Collections.synchronizeMap(hashMap);

Iterator vs Enumeration

  • Iterator has a remove() method while Enumeration doesn't.
  • Enumeration is very basic and twice as fast as Iterator and uses very less memory. 
  • Iterator is more secure and safe as compared to Enumeration because it  does not allow other thread to modify the collection object while some thread is iterating over it and throws ConcurrentModificationException.
  • Enumeration has two methods and both are available in iterator. Method names for both of them are shortened.

 Fail Fast vs Fail Safe

  • Fail fast means not concealing the error, bringing it out as soon as its detected.
  • Business is obstructed, but we get a chance to rectify.
  • Fail-Fast results in interrupted availability, over a period it results in a robust system.
  • Fail ensures system doesn't continue after a failure and creates data corruption and irreversible changes.
  • Fail Fast is a better approach in most scenarios but for life critical, mission critical applications we need fail safe programs and not fail fast. Fail-Safe is Achieved with Exception Handling.

Fail Fast Iterator vs Fail Safe Iterator

  • Difference between Fail Safe Iterator and Fail Fast Iterator is same as discussed above.
  • Iterator of CopyOnWriteArrayList is an example of fail-safe Iterator also iterator written by ConcurrentHashMap keySet is also fail-safe iterator and never throw ConcurrentModificationException in Java.

ConcurrentHashMap vs Collections.synchronizedMap vs Hashtable vs Hashmap

  • Collections.synchronizedMap provide a basic thread-safe implementation of Map. 
  • Collections.synchronizedMap has fail-fast iterator and single collection-wide lock, which at times is obstruction to scalability and concurrency. 
  • Collections.synchronizedMap and Hashtable give poor performance if the size is large due to single collection-wide lock.
  • ConcurrentHashMap implementations provide much higher concurrency while preserving thread safety. 
  • ConcurrentHashMap introduced concept of segmentation , ConcurrentHashMap only locked certain portion of Map to provide thread safety so many other readers can still access map without waiting for iteration to complete.
  • ConcurrentHashMap do not allow null keys or null values while HashMap allows null keys.

Interfaces vs Abstract Classes

  • Interface in Java can only contains declaration.
  • Abstract class may contain both abstract and concrete methods, which makes abstract class an ideal place to provide common or default functionality.
  • A class can inherit multiple interfaces, but it can inherit only one abstract class.
  • By extending abstract class, a class can only participate in one Type hierarchy but by using interface it can be part of multiple type hierarchies.
  • Methods in an abstract class can be protected, private, static etc. But, all items in an interface are implicitly public. 
  • Abstract classes can contain fields that are not static and final.
  • Interface defines a CAN-DO relationship, Classes (including Abstract) than IS-A relationship.
  • In comparison with java abstract classes, java interfaces are slow as it requires extra indirection.

Vector vs ArrayList

  • Vector and ArrayList are derived from AbstractList and implements List interface, which means both of them are ordered collection and allows duplicates.
  • Vector vs ArrayList is that both are index based Collection and you can use get(index) method to retrieve objects from Vector and ArrayList.
  • All the methods of Vector are synchronized and methods of ArrayList are not synchronized.
  • Both the ArrayList and Vector hold onto their contents using an Array.
  • A Vector defaults to doubling the size of its array, while the ArrayList increases its array size by 50 percent.

Vector vs ArrayList vs LinkedList

  • LinkedList is implemented as a double linked list. Its performance on add and remove is better than Arraylist, but worse on get and set methods.
  • LinkedList also implements Queue interface which adds more methods than ArrayList and Vector, such as offer(), peek(), poll(), etc.
  • While an ArrayList uses an array internally to store the data, a LinkedList uses nodes to hold the elements.
  • LinkList is a series of instances of a private nested class Entry, which has next, previous and element references.

Dictionary & Properties

  • Dictionary is an abstract class. Map is an interface.
  • Dictionary is parent class of Hashtable.
  • Properties is child class of Hashtable.
  • Properties represents a persistent set of properties.
  • Each key and its corresponding value in the property list is a string, while in hashtable it can be any object.
  • Properties is thread safe.
  • Properties is a very specialized class that's designed to hold configuration and/or resources that are usually stored in some file.
  • Properties supports reading and writing its content to a well-defined plain-text format (using load()/store())
  • Properties supports reading and writing its content to a well-defined XML-based format (using loadFromXML()/storeToXML())
  • The Dictionary class is the abstract parent of any class, such as Hashtable, which maps keys to values.

Wait vs Sleep

  • sleep() allows the thread to go to sleep state for x milliseconds. When a thread goes into sleep state it doesn’t release the lock. 
  • wait() allows thread to release the lock and goes to suspended state. The thread is only active when a notify() or notifAll() method is called for the same object.

Notity vs Notify All

  • notify( ) wakes up the first thread that called wait( ) on the same object.
  • notifyAll( ) wakes up all the threads that called wait( ) on the same object. The highest priority thread will run first. 

Java SE(Standard Edition) vs Java EE(Enterprise Edition) vs Java ME(Micro Edition)

  • Java SE - Plain vanilla version of Java. Java SE has a large library of code which includes many utilities, algorithms, data structures etc. Java EE and Java ME are built on top of Java SE.
  • Java EE - Builds on Java SE. Java EE contains additional libraries of code and development tools that are uniquely useful in developing web-based business applications.
  • Java ME - A reduced version of Java SE and an associated library of software that addresses the unique needs of Java applications that should run on limited capability devices like mobile phones and PDAs.


The list will continue, please contribute.