Sunday, May 10, 2015

Java SE 5... What's New? (Part 01/04)

I have provided some of the most important core language enhancements for JDK 5.0, along with code samples. The examples provided below can be directly pasted into your IDE and you may name the class as provided.


Type Safe Enumerations
Enumerations are provided as an easier way to maintain similar values (constants) that can be assigned to a type. The keyword used is enum. You may additionally define constructors. The method ordinal() will return 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. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_Enum {  
      public static enum Java {JDK5, JDK6, JDK7, JDK8};  
      public static enum JavaVer {   
           JDK5(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.JDK5);  
           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 JDK5: {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
Varargs should be provided as the last parameter of any method and can be used to pass zero or more arguments to the method. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_Varargs {  
      public void getData(String...values) {  
           for(String string:values) {  
                System.out.println(string);  
           }  
      }  
     
      public static void main(String[] args) {  
           jdk5_Varargs varargs = new jdk5_Varargs();  
           varargs.getData("Apple","Banana","Cucumber","Radish");       
           String[] vargs = new String[] {"Radia","Cloud","Hewlett","Packard"};  
           varargs.getData(vargs);  
      }  
 }  


Generics
Generics is used to maintain compile-time type safety on code. It follows type erasure and allows to maintain a control over the types that can be maintained in collections. You may also use generics to define method or class 'templates'. You may directly execute the code below in Eclipse to understand better. For more on generics, refer to my article in CodeGuru.
 public class jdk5_Generics {  
      List<String> genericList = new ArrayList<String>();  
   
      public static void main(String[] args) {            
           jdk5_Generics jGenerics = new jdk5_Generics();  
           // generic for type safety  
           List<String> 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<Vehicle> rentVehicle = new RentCar<Car>();  
           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 <T extends Vehicle> {  
      public void rentOut(T vehicle);  
 }  
 class RentCar<Car> implements RentVehicle{  
      public void rentOut(Vehicle vehicle) {            
           System.out.println("Rent Vehicle => Rent Car");  
      }  
 }  


Autoboxing/Unboxing
Autoboxing or Unboxing will allow to convert from primitive types to wrapper types and vice versa. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_Autoboxing {  
      Integer integer = new Integer(50);  
      public void setValue(int integer) {  
      }  
      public Integer getValue() {  
           return integer;  
      }  
      public Float getFloat() {  
           return 6.0f;  
      }  
      /**  
       * @param args  
       */  
      public static void main(String[] args) {            
           jdk5_Autoboxing autoboxing = new jdk5_Autoboxing(); // autounboxing  
           autoboxing.setValue(new Integer(5));  
           int x = autoboxing.getValue();  
           // this is not valid => autounboxing - upcasting - autoboxing  
           // Double y = autoboxing.getFloat();  
      }  
 }  


Enhanced For Loop
Enhanced For Loop allows an easier way to loop through objects of a common super-type. You may directly execute the code below in Eclipse to understand better.
 public class jdk5_EnhancedFor {  
      public static void main(String[] args) {  
           jdk5_EnhancedFor ef = new jdk5_EnhancedFor();  
           List<Animal> 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");  
      }  
 }  


Static Imports
Static Imports allows you to import static methods and fields from other classes or interfaces, most useful when you to easily refer to static members from other classes without the reference of their class. You may directly execute the code below in Eclipse to understand better. Note that it is a compile-time error to import a type from 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 'jdk5.features'

 package jdk5.features;
 public class jdk5_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 
Annotations are way of syntactic meta-data to inform and use that it signifies a specific type of functionality that can be processed using reflection. It can also be used to suppress warnings and inform of errors. The source file below is located under the package 'jdk5.features'
 package jdk5.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 jdk5_Annotation_Source {  
 }  

The RetentionPolicy as mentioned can be either of Runtime (Retained by VM), Source (Discarded by Compiler) or Class (Not be Retained by VM). The source below is located under the package 'jdk5.features'
 package jdk5.features;  
 public class jdk5_Annotation_Usage {  
      @jdk5_Annotation_Source  
      public String myMessage;  
      public void annotated() {  
           System.out.println(myMessage);  
      }  
 }  

Now, You may directly execute the code below in Eclipse to understand Annotations better. (Default Package)
 import java.lang.reflect.Field;  
 import jdk5.features.jdk5_Annotation_Source;  
 import jdk5.features.jdk5_Annotation_Usage;  
 
 public class jdk5_AnnotationProcessor {  
      public static void main(String[] args) throws Exception {  
           jdk5_Annotation_Usage message = new jdk5_Annotation_Usage();  
           Field[] method = message.getClass().getDeclaredFields();  
           for(Field methd: method) {  
                jdk5_Annotation_Source annos = methd.getAnnotation(jdk5_Annotation_Source.class);                 
                if(annos != null) {  
                     methd.set(message,"Messenger of God!");  
                     // using reflection & annotations we set the value - check if set                  
                     message.annotated();   
                }  
           }  
      }  
 }  


Happy Coding with JDK 5!

No comments: