0% found this document useful (0 votes)
2 views18 pages

Module5 Notes

Module 5 covers Enumerations, Autoboxing, Generics, and Annotations in Java. It explains the fundamentals of enumerations, the concept of autoboxing and unboxing, the benefits of using generics for type safety and code reusability, and the basics of creating and using annotations. Examples are provided throughout to illustrate each concept effectively.

Uploaded by

akshusrapati
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views18 pages

Module5 Notes

Module 5 covers Enumerations, Autoboxing, Generics, and Annotations in Java. It explains the fundamentals of enumerations, the concept of autoboxing and unboxing, the benefits of using generics for type safety and code reusability, and the basics of creating and using annotations. Examples are provided throughout to illustrate each concept effectively.

Uploaded by

akshusrapati
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Module 5: Enumerations, Autoboxing, Generics and

Annotations
Object Oriented Programming with JAVA (MOJCA203)
Textbook Reference: Herbert Schildt, Java The Complete Reference, 9th Edition, Chapter
12

1. Enumerations

1.1 Enumeration Fundamentals


An enumeration is a list ofnamed constants that define a new data type. Enumerations are
created using the enum keyword. Once you define an enumeration, you can create a
variable ofthat type, and its values can only be one ofthe enumeration constants.

Syntax:

java
enum EnumName {
CONSTANT1, CONSTANT2, CONSTANT3;
}

Example — Days ofthe Week

java
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class WorkingDayCheck {


public static void main( String[] args) {
for ( Day d : Day. values() ) {
if ( d == Day. SATURDAY | | d == Day. SUNDAY) {
System. out. println( d + " is NOT a working day") ;
} else {
System. out. println( d + " is a working day") ;
}
}
}
}

Key points:
Each enum constant is implicitly public static final .

Enum constants are compared using == or .equals() .


An enum can be used inside a switch statement.

1.2 The values() and valueOf() Methods


Every enum automatically has two useful methods:

Method Description

values() Returns an array containing a list ofthe enumeration constants, in the order
they are declared.

valueOf(String Returns the enumeration constant whose value corresponds to str . An


str) exact match is required, otherwise a IllegalArgumentException is
thrown.

General form:

java
static enum- type[] values()
static enum- type valueOf( String str)

Example — Canteen Food Items

java
enum FoodItem {
PIZZA( false) , BURGER( false) , SALAD( true) ,
CHICKEN_WRAP( false) , FRUIT_BOWL( true) ;

private boolean vegetarian;

FoodItem( boolean vegetarian) {


this. vegetarian = vegetarian;
}

boolean isVegetarian() {
return vegetarian;
}
}

public class Canteen {


public static void main( String[] args) {
for ( FoodItem item : FoodItem. values() ) {
System. out. println( item + " - " +
( item. isVegetarian() ? " Vegetarian" : " Non- Vegetarian") ) ;
}

// valueOf() demonstration
FoodItem chosen = FoodItem. valueOf(" SALAD") ;
System. out. println(" Selected item: " + chosen + ", Vegetarian: " + chos
}
}

1.3 Java Enumerations Are Class Types


Unlike enumerations in C/C++, a Java enum defines a class type. This means an enum can
have:

Constructors
Instance variables and methods
Its own body

Rules:

Each enum constant is an object ofits enum type.


When you define a constructor for an enum, it is called automatically each time an
enum constant is created.
Enum constructors are always private (or default), since they can only be called from
within the enum itself.
An enum can implement interfaces but cannot extend another class (it implicitly
extends [Link] ).

Example — Employee Types with Health Insurance Eligibility

java
enum EmployeeType {
FULL_TIME(" Eligible for health insurance") ,
PART_TIME(" Eligible for health insurance") ,
INTERN(" Not eligible") ,
CONTRACT(" Not eligible") ;

private String insuranceStatus;

// enum constructor - implicitly private


EmployeeType(String insuranceStatus) {
this. insuranceStatus = insuranceStatus;
}

boolean isInsuranceEligible() {
return this == FULL_TIME | | this == PART_TIME;
}
}

public class HRSystem {


public static void main( String[] args) {
for ( EmployeeType type : EmployeeType. values() ) {
System. out. println( type + " -> " + type. insuranceStatus +
" (" + type. isInsuranceEligible() + ") ") ;
}
}
}
Example — Subscription Plans with Multiple Fields (based on QB Module 5, [Link] 13):

java
enum SubscriptionPlan
{ BASIC( 1, false) ,
STANDARD( 2, false) ,
PREMIUM( 4, true) ,
ULTRA( 4, true) ;

private int screens;


private boolean isAdFree;

SubscriptionPlan( int screens, boolean isAdFree) {


this. screens = screens;
this. isAdFree = isAdFree;
}

int getScreens() { return screens; }


boolean isAdFree() { return isAdFree; }
}

public class Netflix {


public static void main( String[] args) {
System. out. println(" Plans with more than 2 screens & ad- free: ") ;
SubscriptionPlan best = null;

for ( SubscriptionPlan plan : SubscriptionPlan. values() ) {


if ( plan. getScreens() > 2 && plan. isAdFree() ) {
System. out. println( plan) ;
if ( best == null | | plan. getScreens() > best. getScreens() )
best = plan;
}
}
System. out. println(" Best plan: " + best) ;
}
}

1.4 Type Wrappers


Java uses primitive types ( int , char , double , boolean , etc.) for performance reasons —
but manyAPIs (like Collections) work only with objects. Wrapper classes provide a way to
wrap primitive values inside objects.
Primitive Wrapper Class

byte Byte

short Short

int Integer

long Long

float Float

double Double

char Character

boolean Boolean

All the numeric wrapper classes inherit the abstract class Number , which declares methods
like intValue() , doubleValue() , etc.

Example:

java
Integer iObj = new Integer( 100) ; // deprecated but conceptually valid
int i = iObj. intValue() ; // unwrapping
double d = iObj. doubleValue() ;

Character ch = new Character(' A' ) ;


char c = ch. charValue() ;

1.5 Autoboxing
Autoboxing is the automatic conversion that the Java compiler performs between
primitive types and their corresponding object wrapper classes. The reverse process is
called unboxing.

java
int primitive = 10;
Integer wrapped = primitive; // autoboxing: int - > Integer
int back = wrapped; // unboxing: Integer - > int

Autoboxing also applies automatically when:


Passing a primitive as a parameter to a method expecting the corresponding wrapper
object.
Assigning a primitive value to an object reference ofthe wrapper type.
In expressions and array elements.

Autoboxing and Methods: Autoboxing lets you pass a primitive type to a method that
expects an object, and lets a method return a primitive that is automatically boxed into an
object.

Example:

java
public class AutoboxDemo {

// method expects an Integer object - > autoboxing happens automatically whe


static void display( Integer value) {
System. out. println(" Boxed value: " + value) ;
}

// returns Integer, but return statement uses a primitive int - > autoboxed
static Integer square( int n) {
return n * n; // autoboxing on return
}

public static void main( String[] args) {


display( 25) ; // autoboxing: int literal - > Integer

Integer result = square( 6) ; // 36 gets autoboxed into an Integer


int val = result; // unboxing back to int

System. out. println(" Square: " + result) ;


System. out. println(" Unboxed: " + val) ;

// Autoboxing in collections ( common real use case)


java. util. List<Integer> marks = new java. util. ArrayList<>() ;
marks. add( 90) ; // int autoboxed to Integer
marks. add( 85) ;
int total = 0;
for ( int m : marks) { // Integer unboxed to int
total += m;
}
System. out. println(" Total: " + total) ;
}
}
2. Generics

2.1 What Are Generics?


Generics enable you to write classes, interfaces, and methods that operate on a type
parameter, allowing the same code to work with different data types safely. Generics
provide compile-time type safety, eliminating the need for explicit casting and reducing
the risk of ClassCastException at runtime.

Benefits:

Type-safety — errors are caught at compile time instead ofruntime.


Code reusability — a single generic class works for multiple data types.
Eliminates the need for typecasting.

2.2 A Simple Generics Example


General form ofa generic class w ith a single type parameter:

java
class ClassName<T>
{ T obj;
ClassName(T o) { obj = o; }
T getObj() { return obj; }
}

Example — Vehicle Registration System

java
class Vehicle<T> {
private T registrationNumber;
private T ownerName; // could also use a second type parameter ( see 2. 3)
private int engineCapacity;

Vehicle( T registrationNumber, T ownerName, int engineCapacity) {


this. registrationNumber = registrationNumber;
this. ownerName = ownerName;
this. engineCapacity = engineCapacity;
}

void display() {
System. out. println(" Reg No: " + registrationNumber +
", Owner: " + ownerName + ", Engine CC: " + engineCapacity) ;
}
}

public class VehicleDemo {


public static void main( String[] args) {
Vehicle<String> v1 = new Vehicle<>(" KA09MJ1234", " Ramesh", 150) ;
v1. display() ;
}
}

2.3 AGeneric Class with Two Type Parameters


A generic class can accept more than one type parameter, separated by commas: class
ClassName<T, U> { ... }

Example — LibraryResource

java
class LibraryResource<T, U>
{ private T resourceId;
private U resourceTitle;
private boolean isAvailable;

LibraryResource( T resourceId, U resourceTitle, boolean isAvailable) {


this. resourceId = resourceId;
this. resourceTitle = resourceTitle;
this. isAvailable = isAvailable;
}

void display() {
System. out. println("ID: " + resourceId + " | Title: " + resourceTitle +
" | Available: " + isAvailable) ;
}
}

public class LibrarySystem {


public static void main(String[] args) {
LibraryResource<Integer, String> book =
new LibraryResource<>( 101, " Java The Complete Reference", true) ;

LibraryResource<String, String> journal =


new LibraryResource<>(" J- 45", " IEEE Transactions", false) ;

book. display() ;
journal. display() ;
}
}

Example — Patient Records

java
class Patient<T, U> {
T id;
U name;
double temperature;

Patient( T id, U name, double temperature) {


this. id = id;
this. name = name;
this. temperature = temperature;
}

void display() {
System. out. println(" Patient ID: " + id + ", Name: " + name +
", Temp: " + temperature + " °F") ;
}
}

public class Hospital {


public static void main( String[] args) {
Patient<Integer, String> p1 = new Patient<>( 1, " Anita", 98. 6) ;
Patient<String, String> p2 = new Patient<>(" P- 002", " Rahul", 101. 2) ;
p1. display() ;
p2. display() ;
}
}

2.4 The General Form ofa Generic Class

java
class GenericClassName<T1, T2, . . . , Tn> {
// T1, T2, . . . Tn act as placeholders for actual types
// supplied when an object of the class is created
}

// Object creation:
GenericClassName<Type1, Type2, . . . , TypeN> obj = new GenericClassName<>(. . . ) ;

T , U , E , K , V are conventional (but not mandatory) type-parameter names.


Type parameters cannot be primitive types ( int , char ) — only reference/wrapper
types are allowed (e.g. Integer , not int ).
Bounded type parameters can restrict the types that may be used, e.g. <T extends
Number> .
Example —

java
class Order<T, U>
{ private T orderId;
private U customerName;
private double price;

Order( T orderId, U customerName, double price) {


this. orderId = orderId;
this. customerName = customerName;
this. price = price;
}

void display() {
System. out. println(" Order#" + orderId + " by " + customerName + " = ₹"
}
}

public class ECommerce {


public static void main( String[] args) {
Order<Integer, String> o1 = new Order<>( 501, " Kiran", 2499. 0) ;
Order<String, String> o2 = new Order<>(" ORD- 77X", " Meena", 899. 50) ;
o1. display() ;
o2. display() ;
}
}

2.5 Creating Generic Methods


Individual methods can also be made generic, even inside a non-generic class. The type
parameter list appears before the return type ofthe method.

General form:

java
<T> returnType methodName( T parameter) { . . . }

Example — Generic method to find maximum oftwo values:

java
public class GenericMethodDemo {

// Generic method – works for any Comparable type


static <T extends Comparable<T>> T findMax(T a, T b) {
return ( a. compareTo( b) > 0) ? a : b;
}

public static void main( String[] args) {


System. out. println(" Max int: " + findMax( 45, 78) ) ;
System. out. println(" Max double: " + findMax( 3. 14, 2. 71) ) ;
System. out. println(" Max string: " + findMax(" Mango", " Apple") ) ;
}
}

Example — Generic printStats-style method (overloading concept, extended with


generics):

java
public class ArrayUtil {
// generic method that works with any array of Comparable elements
static <T extends Comparable<T>> T findLargest(T[] arr) {
T max = arr[0] ;
for ( T item : arr) {
if ( item. compareTo( max) > 0) max = item;
}
return max;
}

public static void main( String[] args) {


Integer[] nums = {12, 45, 3, 89, 21};
String[] names = {" Zara", " Amit", " Divya"};

System. out. println(" Largest number: " + findLargest( nums) ) ;


System. out. println(" Largest ( alphabetically last) name: " + findLargest
}
}

SLT — Som e Generic Restrictions (to remember):

You cannot create an instance ofa type parameter, e.g. T obj = new T(); is illegal.
You cannot create an array ofa generic type in most cases, e.g. T[] arr = new T[10];
is illegal.
Generic class type parameters cannot be used in static members, since static
members belong to the class, not to a specific parameterized instance.
You cannot use primitive types as type arguments — use wrapper classes instead.

3. Annotations

3.1 Annotation Basics


An annotation is created via an @interface declaration. Annotations provide metadata
about a program element (class, method, field, etc.) that can be processed at compile time or
retrieved at run time through reflection. Annotations do not directly affect program
execution, but tools and frameworks can act upon the information they carry.

Defining a custom annotation:

java
import java. lang. annotation. *;

@Retention( RetentionPolicy. RUNTIME) // makes the annotation available at run


@Target( ElementType. METHOD) // restricts where the annotation may be
@interface TrainerInfo {
String trainerName() ;
String employeeId() ;
double moduleVersion() ;
}

Key meta-annotations used when defining custom annotations:

Meta- Purpose
annotation

@Retention Specifies how long the annotation is retained ( SOURCE , CLASS , or RUNTIME ).
Must be RUNTIME to read it via reflection.

@Target Restricts the kind ofelement ( METHOD , FIELD , TYPE , etc.) the annotation can
be applied to.

@Inherited Allows a subclass to inherit an annotation from its superclass.

@Documented Includes the annotation in generated Javadoc.

3.2 Obtaining Annotations at Run Time by Use ofReflection


The [Link] package (specifically the Method , Class , and Field classes) is
used to inspect annotations at run time.

Example — Corporate Training System

java
import java. lang. annotation. *;
import java. lang. reflect. *;

@Retention( RetentionPolicy. RUNTIME)


@Target( ElementType. METHOD)
@interface TrainerInfo {
String trainerName() ;
String employeeId() ;
double moduleVersion() ;
}

class TrainingModule {

@TrainerInfo( trainerName = " Suresh Kumar", employeeId = " EMP101", moduleVer


public void conductJavaModule() {
System. out. println(" Conducting Java Training Module. . . ") ;
}

@TrainerInfo( trainerName = " Divya Rao", employeeId = " EMP205", moduleVersio


public void conductDatabaseModule() {
System. out. println(" Conducting Database Training Module. . . ") ;
}
}

public class ReflectionDemo {


public static void main( String[] args) throws Exception {
Class<?> cls = TrainingModule. class;

for ( Method m : cls. getDeclaredMethods() ) {


if ( m. isAnnotationPresent( TrainerInfo. class) )
{ TrainerInfo info = m. getAnnotation( TrainerInfo. class) ;
System. out. println(" Method: " + m. getName() ) ;
System. out. println(" Trainer: " + info. trainerName() ) ;
System. out. println(" Employee ID: " + info. employeeId() ) ;
System. out. println(" Module Version: " + info. moduleVersion() )
}
}
}
}

Example — Banking Audit System


java
import java. lang. annotation. *;
import java. lang. reflect. *;

@Retention( RetentionPolicy. RUNTIME)


@Target( ElementType. METHOD)
@interface AuditInfo {
String auditorName() ;
String auditId() ;
String level() ;
}

class BankTransaction {
@AuditInfo( auditorName = " R. Sharma", auditId = " AUD- 901", level = " High")
public void processTransfer() {
System. out. println(" Processing fund transfer. . . ") ;
}
}

public class AuditReflectionDemo {


public static void main( String[] args) throws Exception {
Method method = BankTransaction. class. getMethod(" processTransfer") ;

if ( method. isAnnotationPresent( AuditInfo. class) ) {


AuditInfo audit = method. getAnnotation( AuditInfo. class) ;
System. out. println(" Transaction reviewed by: " + audit. auditorName(
System. out. println(" Audit ID: " + audit. auditId() + ", Level: " + a
}
}
}

3.3 Built-in Annotations


Java provides several standard annotations in [Link] and [Link] :
Annotation Description

@Override Indicates that a method overrides a method in its superclass; compiler


checks this and reports an error ifnot true.

@Deprecated Marks a program element as obsolete; compiler generates a warning if


it is used.

@SuppressWarnings Instructs the compiler to suppress specific warnings (e.g. unchecked ,


deprecation ).

@FunctionalInterface Indicates that an interface is intended to be a functional interface


(exactly one abstract method).

@SafeVarargs Suppresses "unsafe" warnings for varargs methods that use generics.

Example:

java
class Base {
void show() { System. out. println(" Base show() ") ; }
}

class Derived extends Base


{ @Override
void show() { System. out. println(" Derived show() ") ; }

@Deprecated
void oldMethod() { System. out. println(" This method is outdated") ; }

@SuppressWarnings(" unchecked")
void useRawList() {
java. util. List list = new java. util. ArrayList() ;
list. add(" Sample") ;
}
}

Quick Revision Summary

Concept Key Idea

Enum Fundamentals enum defines a fixed set ofnamed constants


Concept Key Idea

values() / valueOf() Iterate constants / convert String → constant

Enums as Class Types Enums can have constructors, fields, methods; implicitly extend Enum

Type Wrappers Object representation ofprimitives ( Integer , Double , etc.)

Autoboxing Automatic primitive ⇌ wrapper conversion done by the compiler

Generics Type-safe, reusable classes/methods using type parameters <T>

Generic Class (2 params) class Name<T, U> { ... }

Generic Methods <T> returnType method(T param)

Annotations Metadata via @interface ; read at run time using reflection

Built-in Annotations @Override , @Deprecated , @SuppressWarnings , etc.

You might also like