IntegerCache in JDK1.5


What is the O/p of following ?

Integer i1 = 20;
Integer i2 = 20;
Integer i3 = 200;
Integer i4 = 200;

if(i1 == i2){
System.out.println("True");
}else{
System.out.println("False");
}

if(i3 == i4){
System.out.println("True");
}else{
System.out.println("False");
}

if(Integer.valueOf(20) == Integer.valueOf(20)){
System.out.println("True");
}else{
System.out.println("False");
}

if(Integer.valueOf(200) == Integer.valueOf(200)){
System.out.println("True");
}else{
System.out.println("False");
}

The answer is
True
False
True
False
It is because in JDK1.5 there is a new concept called Caching Integer Objects.

Until JDK1.5 it didn’t matter whether to use Integer.valueof() or new Integer() methods to create an integer object.But with the jdk1.5 feature it is recommended to use Integer.valueOf().

Reason : In JDK1.5 the JVM caches Integer objects from range of -128 to 127 . So every time an integer object is create with value between the above mentioned range same object will be returned instead of creating the new object.

For the given statement
Integer i1 = 20.
The autoboxing features come into play which uses again the Integer.valueOf() method to create an object and every time will return same object.

Note: This will not happen for Integer i1 = new Integer(20). // Something similar to String pool

The Integer class has an inner class called IntegerCache with the following implementation.

private static class IntegerCache {
static final int high;
static final Integer cache[];

static {
final int low = -128;

int h = 127;
if (integerCacheHighPropValue != null) {
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;

cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}

private IntegerCache() {}
}

Since its an inner class, so the 256 objects will not be created until it is called for the first time. Hence, initial loading of the first integer object will be slow as cache array with 256 objects will be created.

The valueOf() method implementation is :


public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}

Spurious wakeup in Java


If a waiting thread wakes up without notify being called it is called Spurious wakeup.
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
… // Perform action appropriate to condition

}

}

This is the standard idiom to use wait() method.  In above scenario if a notify() is sent by any other thread then the condition will not hold and wait() will be skipped. Consider if there is no while loop and some other thread calls notify before wait() is called by this thread, then it may happen that it could wait forever or till next notify is called.

The javadoc of wait method in JDK 5 has also been updated

A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops

Src : Effective Java By Joshua Bloch

Implementing Set using arrays


it is part of my assignement.. 

public class Set<T> {

      private T arrayElement[];

      int size =0;

      public Set(){

            this.arrayElement = null;

      }

      public Set(T[] element){

            arrayElement = element;

            size = arrayElement.length;

      }

      /**

       *add element to set. A check is made to identify whether element is present or not.

       *If not the element can be inserted.

       * @param element

       */

      public void addElement(T element){

            if(!contains(element)){

            if(size == arrayElement.length){

                  incrementArray();

            }

            arrayElement[size++] = element;

            }

      }

     

      /**

       * to check is element is present or not.

       * @param elem

       * @return boolean

       */

      public boolean contains(T elem){

 

            if (elem == null) {

                for (int i = 0; i < size; i++)

                  if (arrayElement[i]==null)

                      return true;

            } else {

                for (int i = 0; i < size; i++)

                  if (elem.equals(arrayElement[i]))

                      return true;

            }

            return false;

         

      }

     

      /**

       * return the size of set.

       * @return int

       */

      public int size(){

            if(arrayElement != null){

                  return arrayElement.length;

            }else

                  return 0;

      }

     

      public void clear(){

            arrayElement = null;

      }

     

      public String toString(){

            if(arrayElement == null  || arrayElement.length ==0 ){

                  return“[EMPTY]”;

            }else{

                  String toStr=”[“;

                  for(int i=0;i<arrayElement.length;i++){

                        toStr+=arrayElement[i]+”,”;

                  }

                  toStr+=”]”;

                  return toStr;

            }

      }

     

      /**

       * to check whether set is empty or not

       * @return

       */

      public boolean isEmpty(){

            if(arrayElement == null || arrayElement.length ==0 )

            return true;

            else

                  return false;

      }

     

      /**

       * this function is used to increment the size of an array

       *

       */

      private void incrementArray(){

            T[] temparray = arrayElement;

            int tempsize=size+5;

             arrayElement =(T[]) new Object[tempsize];

             System.arraycopy(temparray, 0, arrayElement, 0, size);

             

      }

}//Set class ends

Can a static block throw exception?


Yes, static block can throw only Runtime exception or can use a try-catch block to catch checked exception.
Typically scenario will be if JDBC connection is created in static block and it fails then exception can be caught, logged and application can exit. If System.exit() is not done, then application may continue and next time if the class is referred JVM will throw NoClassDefFounderror since the class was not loaded by the Classloader.