SKP's Java / Java EE Gotchas: Revisiting Java SE 5 Features!
In celebration of Java 9's pending arrival (and in preparation for any interviews you might have), let's go over what SE 5 introduced, including annotations and varargs.
Join the DZone community and get the full member experience.
Join For FreeSo, preparing for an interview? Want to revisit some Java SE 5 features? Trying to recall or revise a Java SE programming construct? Let me take you back in time to what was introduced first in Java SE 5! This progression and tutorial series on Java, as we all eagerly await the official release of Java SE 9!
Java SE 5 Release Date: 04-10-2004
Java SE 5 Code Name: Tiger
Java SE 5 Highlights
Metadata, Generic Types, Autoboxing and Auto-Unboxing of Primitive Types, Enhanced
for
LoopEnumerated Types, Static Import, Formatted I/O, Varargs, and Concurrency Utilities.
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.
XML 1.1 with Namespaces, XML Schema, SAX 2.0.2, DOM Level 3, XSLT with a Fast XLSTC compiler.
Unicode 4.0 Support
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.
Typesafe 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 are used to maintain compile-time type safety on code. It follows type erasure and allows us to maintain 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 it 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 you to convert from primitive types to wrapper types and vice versa. You may directly execute the code below in Eclipse to understand it 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 loops allow for an easier way to loop through objects of a common super-type. You may directly execute the code below in Eclipse to understand it 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 allow you to import static methods and fields from other classes or interfaces. They are most useful when you want 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 it better. Note that it is a compile-time error to 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 '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 a syntactic metadata used to inform and signify 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 the VM), Source (discarded by the compiler), or Class (not be retained by the 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!
Here is the GitHub link with code samples from the article and more!
Published at DZone with permission of Sumith Puri. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments