dcsimg

Java History: Core Java 5 Features

In this article we begin our series on the programming language Java and its history. We look at different releases, new features added in each release, and code samples from those releases. We begin with Java SE 5.

Below are the release details and new feature list for Java SE 5:

  • Java SE 5 Release Date: 04-10-2004 Java SE 5 Code Name: Tiger
  • Java SE 5 New Feature List (provided by Oracle Documentation)

Metadata, Generic Types, Autoboxing and Auto-Unboxing of Primitive Types, Enhanced for Loop Improved Startup Time and Memory Footprint. Sharing of Read-Only Data between Multiple Running JVMs. Remote Monitoring and Management. A New JVM profiling API. Programmatic Generation of Stack Traces. Unicode 4.0 Support Enumerated Types, Static Import, Formatted I/O, Varargs, Concurrency Utilities.

Enhanced For Loops in Java

Java 5 introduced the enhanced for loop to allow an easier way to loop through objects of a common super type. Here is an example of how to use enhanced for loops in Java 5:

 public class java5_EnhancedFor {   

    public static void main(String[] args) {   
       java5_EnhancedFor ef = new java5_EnhancedFor();   
       List animals = new ArrayList();   
       Animal animal = new Animal();   
       animals.add(animal);   
       animal = new Dog();   
       animals.add(animal);   
       animal = new Cat();   
       animals.add(animal);   
       animal = new Dog();   
       animals.add(animal);   
       animal = new Cat();   
       animals.add(animal);   
       animal = new Dog();   
       animals.add(animal);   
       animal = new Animal();   
       animals.add(animal);   
       animal = new Animal();   
       animals.add(animal);   
       for(Animal anim: animals) {   
         anim.print();   
       }   
    }   
  }   

  class Animal {   
    public void print() {   
       System.out.println("Animal");   
    }   
  }   

  class Dog extends Animal {   
    public void print() {   
       System.out.println("Dog");   
    }   
  }   

  class Cat extends Animal {   
    public void print() {   
       System.out.println("Cat");   
    }   
  }   

Java Static Imports in Java 5

Static imports allow you to import static methods and fields from other classes or interfaces. It is beneficial when a developer wants to quickly refer to static members from other classes without the reference to a class. It will result in a compile-time error if you import a type from an unnamed or default package.

 
 import static jdk5.features.jdk5_StaticImport_Source.product;   
  public class jdk5_StaticImport {   
    public static void main(String[] args) {   
       System.out.println(product);   
    }   
   } 

The source for importing the above is the following class, which is located under the package: java5.features

  package java5.features;  
  
  public class java5_StaticImport_Source {   
    public static final String product = "radia-cloud";   
    public static final String version = "09.20.0000";   
  
   public static void setup() {   
       System.out.println("Setting up the Radia Server....");   
    }   
 
    public static void init() {   
       System.out.println("Initializing the Radia Server....");   
    }   
  }   

Annotations in Java 5

Annotations are a way of using syntactic metadata to signify a specific type of functionality that can be processed using reflection. Annotations can also be used to suppress warnings and to inform the developer of any errors.

Here is an example of using annotations in Java 5:

 
  package java5.features;   
 
  import java.lang.annotation.ElementType;   
  import java.lang.annotation.Retention;   
  import java.lang.annotation.RetentionPolicy;   
  import java.lang.annotation.Target;   
 
  @Retention(RetentionPolicy.RUNTIME)   
  @Target({ElementType.FIELD,ElementType.METHOD})   
  public @interface java5_Annotation_Source {   
  }   

The RetentionPolicycan be any of the following: Runtime - Retained by the virtual machine (VM). Source - Discarded by the compiler. Class - Not retained by the virtual machine (VM).

  package java5.features;   
  
  public class java5_Annotation_Usage {   
   
    @java5_Annotation_Source   
    public String myMessage;   
  
    public void annotated() {   
       System.out.println(myMessage);   
    }   
  }   

To better understand how annotations work in Java 5, try executing the following code in an Integrated Development Environment (IDE) and observe the result:

(Default Package)

  import java.lang.reflect.Field;   
  import java5.features.java5_Annotation_Source;   
  import java5.features.java5_Annotation_Usage;   
    
  public class java5_AnnotationProcessor {   

    public static void main(String[] args) throws Exception {   
       java5_Annotation_Usage message = new java5_Annotation_Usage();   
       Field[] method = message.getClass().getDeclaredFields();   
       for(Field methd: method) {   
         java5_Annotation_Source annos = methd.getAnnotation(java5_Annotation_Source.class);           
         if(annos != null) {   
            methd.set(message,"Messenger of God!");   
            // using reflection & annotations we set the value - check if set           
            message.annotated();    
         }   
       }   
    }   
  }   

Autoboxing and Unboxing in Java 5

To convert from primitive types to wrapper types - and vice versa - autoboxing and unboxing was introduced into Java 5. Here is an example of how they work:

  public class java5_Generics {   
    List genericList = new ArrayList();   
     
    public static void main(String[] args) {        
       java5_Generics jGenerics = new java5_Generics();   
       // generic for type safety   
       List jGenericsList = jGenerics.genericList;   
       jGenericsList.add("Sumith");   
       jGenericsList.add("Kumar");   
       jGenericsList.add("Puri");   
       for(String str:jGenericsList) {   
         System.out.println(str);   
       }   

       // generic variables - class and method generic templates   
       List<? extends Vehicle> jGenericObjList = new ArrayList();   
       Vehicle car = new Car();   
       RentVehicle rentVehicle = new RentCar();   
       rentVehicle.rentOut(car);   
    }   
  }   

  class Vehicle {   
    Integer regn;   
    String type;   

    public Integer getRegn() {   
       return regn;   
    }   

    public void setRegn(Integer regn) {   
       this.regn = regn;   
    }   

    public String getType() {   
       return type;   
    }   

    public void setType(String type) {   
       this.type = type;   
    }        
  }   

  class Car extends Vehicle {   
  }   

  interface RentVehicle  {   

    public void rentOut(T vehicle);   
  }   

  class RentCar implements RentVehicle{   
    public void rentOut(Vehicle vehicle) {        
       System.out.println("Rent Vehicle => Rent Car");   
    }   
  }   

Type Safe Enumerations in Java 5

To maintain similar values - or constants - that can be assigned to a type, enumerations were introduced as an easier method. The keyword used for enumerations is enum. One may additionally define constructors - the method ordinal() returns the index of the enum constant and the method name() will return the name of the enum constants. You may also use valueOf() to return the value of a string as an enum constant.

Try out the following code for using enumeration in Java:

 
public class java5_Enum {   
    public static enum Java {Java5, JDK6, JDK7, JDK8};   
    public static enum JavaVer {    
       Java5(5), JDK6(6), JDK7(7), JDK8(8);   
       int x;   
       JavaVer(int x) {   
         this.x = x;   
       }   
    }   
      
    public static void main(String[] args) {   

       Java java = Java.JDK6;   
       System.out.println(Java.Java5);   
       System.out.println(java);   
       System.out.println(java.ordinal() + ":" + java.name());   
       JavaVer javaVer = JavaVer.JDK7;   
       System.out.println(javaVer.x);   
       System.out.println(javaVer.ordinal() + ":" + javaVer.name());   
       String myJava = "JDK8";   
       System.out.println(Java.valueOf(myJava));   
       JavaVer javaSwitchVer=JavaVer.JDK6;   

       switch(javaSwitchVer) {   
         case Java5: {System.out.println("5.0"); break;}   
         case JDK6: {System.out.println("6.0"); break;}   
         case JDK7: {System.out.println("7.0"); break;}   
         case JDK8: {System.out.println("8.0"); break;}   
       }   
    }   
  }   


Variable Arguments in Java 5

The last parameter of any method that can also be used to pass zero or more arguments to the method is Varargs. Here is an example in Java code:

 

  public class java5_Varargs {   
    public void getData(String...values) {   
       for(String string:values) {   
         System.out.println(string);   
       }   
    }   
      
    public static void main(String[] args) {   
       java5_Varargs varargs = new java5_Varargs();   
       varargs.getData("Apple","Banana","Cucumber","Radish");      
       String[] vargs = new String[] {"Radia","Cloud","Hewlett","Packard"};   
       varargs.getData(vargs);   
    }   
  }   


Generics in Java 5

To maintain compile-time type safety in Java, developers can use generics. Type erasure is used in generics and it allows you to maintain control over the types that can be maintained in collections. Generics may also be used to define method or class 'templates'. Try out the following code showing how to use generics in Java 5:

  public class java5_Generics {   
    List genericList = new ArrayList();   
     
    public static void main(String[] args) {        
       java5_Generics jGenerics = new java5_Generics();   
       // generic for type safety   
       List jGenericsList = jGenerics.genericList;   
       jGenericsList.add("Sumith");   
       jGenericsList.add("Kumar");   
       jGenericsList.add("Puri");   
       for(String str:jGenericsList) {   
         System.out.println(str);   
       }   
       // generic variables - class and method generic templates   
       List<? extends Vehicle> jGenericObjList = new ArrayList();   
       Vehicle car = new Car();   
       RentVehicle rentVehicle = new RentCar();   
       rentVehicle.rentOut(car);   
    }   
  }   
  class Vehicle {   
    Integer regn;   
    String type;   
    public Integer getRegn() {   
       return regn;   
    }   
    public void setRegn(Integer regn) {   
       this.regn = regn;   
    }   
    public String getType() {   
       return type;   
    }   
    public void setType(String type) {   
       this.type = type;   
    }        
  }   
  class Car extends Vehicle {   
  }   
  interface RentVehicle  {   
    public void rentOut(T vehicle);   
  }   
  class RentCar implements RentVehicle{   
    public void rentOut(Vehicle vehicle) {        
       System.out.println("Rent Vehicle => Rent Car");   
    }   
  }   


Read the next part in this series, where we cover Java 6 Core features and new additions!