0% found this document useful (0 votes)
126 views11 pages

Lab Session 13: Generics in Java

1) Generics in Java allow a single class or method to work with multiple data types, eliminating the need for separate classes or methods for each data type. 2) A generic class or method uses type parameters like <T> that can be replaced by any data type, allowing the class or method to accept arguments of different types while still catching type errors at compile time. 3) The example demonstrates defining a generic method that can display arrays of various types like String or Integer, while the compiler ensures only the correct types are added to each array.

Uploaded by

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

Lab Session 13: Generics in Java

1) Generics in Java allow a single class or method to work with multiple data types, eliminating the need for separate classes or methods for each data type. 2) A generic class or method uses type parameters like <T> that can be replaced by any data type, allowing the class or method to accept arguments of different types while still catching type errors at compile time. 3) The example demonstrates defining a generic method that can display arrays of various types like String or Integer, while the compiler ensures only the correct types are added to each array.

Uploaded by

Parsa Shereen
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 11

Object Oriented Programming

BS(SE) 2021
CSS 1042
Department of CS and SE

Lab Session 13: Generics in Java


What are Generics?
Generics in Java is the facility which is provided to the user to make a single method or single class
that can be compatible with any data type like a single method can operate on integer type or string
type or even object type. If you are familiar with template in C++, then you can consider generics as a
template in Java. In simple words, generic methods (or classes) are those methods that are written
with single method declaration and can be called or accessed with arguments of different type.
Let’s understand this with the help of an example. Suppose you have to view an image in your
computer using a software. Consider a scenario where a single software can view or edit only single
image file format, e.g., software A can view only jpg file, software B can view only png file, software
C can view only gif file etc. On the other hand, there is only a single software X which can view any
type of image files.
Now if you have the option to choose any one of the software, which one will you choose? It’s quite
obvious you will choose the software X because having many software will be very inefficient and it
will consume more memory. In the same way, Generics in Java works. Instead of having different
methods and classes for doing the same task, we make only one method or class which will be
compatible with any data type as Integer, Double, String, Employee (object type) etc.
To understand generics, let’s see how it solves issues with collections. Consider the following code
that uses a List collection without generics:
List listNames = new ArrayList();
listNames.add("Tom");
listNames.add("Mary");
listNames.add("Peter");
This list, listNames, is supposed to store String objects. The following statement takes the 2nd
element in this list:
String name2 = (String) listNames.get(1);
Here, the cast to String is needed because the get() method returns an object of type Object.
So far so good. Suppose that at some points in the program, you may be mistakenly adding an object
other than String as the 2nd element in the list:
Date startDate = new Date();
listNames.add(startDate);
This code is still legal, as the add() method can accept any kind of object. Now, a problem will rise in
this statement:
String name2 = (String) listNames.get(1);
Why?
This assignment expects a String object on the right side, but the actual object returned is a Date
object. This problem cannot be detected at compile time by the compiler because everything seems
fine until that statement is executed at runtime, a ClassCastException will be thrown:
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String


What will be the effect?
This kind of problem would produce unsafe code with potential bugs as the type of the objects added
to the collection cannot be verified by the compiler and compile time. Therefore, generics come to
rescue. The above code snippet can be re-written using generics like this:
List<String> listNames = new ArrayList<String>();
listNames.add("Tom");
listNames.add("Mary");
listNames.add("Peter");
Here, the list listNames is parameterized with the String type (read: list of Strings). From now on, if
you mistakenly add a non-String object into this collection, the compiler will issue an error. For
example:
Date startDate = new Date();
listNames.add(startDate);
Compile error message:
cannot find symbol
symbol: method add(java.util.Date)
location: interface java.util.List<java.lang.String>
This generic code is safe as it guarantees all elements added to the collection are of the parameterized
type. Otherwise, a compile error occurs.
With generics, the compiler can detect violations at compile time, thus eliminating potential bugs.
And as a consequence, we don’t need to cast objects when getting an element out of the generic
collection:
String name2 = listNames.get(1);
This is safe, because generics ensure that the collection does not store wrong object types.
Syntax
To create object of generic class or method we follow the below syntax:
abc obj<Type1,Type2,...,Type n> = new abc<Type1,Type2,...,Type n>()
Here Type can be replaced with any data type but remember that it cannot have primitive data types
like int, double, etc. It should be of object type like Integer, Double, String, Float, Employee etc.
There is a general convention for this Type parameter:
T is used for type.
E is used for an element.
N is used for numbers.
K is used for the key.
V is used for the value.
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

Types of Java Generics


There are 4 different ways Generics can be applied to in Java and they are as follows:
● Generic Class and Method
● Generic Interface
● Generic Constructor

Generic Class and Method

A class is said to be Generic if it declares one or more type variables. These variable types are known
as the type parameters of the Java Class.
Generic methods are much similar to generic classes. They differ from each other in only one aspect
that the scope or type information is inside the method only. Generic methods introduce their own
type parameters.
Let’s understand this with an example.
Generic Method Example
public class test {
public < E > void showArray(E[] s) {
for (E x: s)
System.out.println(x);
}
public static void main(String[] args) {
test Obj = new test();
String name[] = new String[] {
"Sachin",
"Virat",
"Dhoni"
};
Integer roll[] = {
10,
23,
44
};
Obj.showArray(name);
Obj.showArray(roll);
}
}
Output
Sachin
Virat
Dhoni
10
23
44
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

In this example, type parameter <E> gets replaced by the string when called with string array and by
integer when called by integer array. The type parameter is placed before the return type of the
method.
We can have more than one parameter type in a method or class. Example:
public class test {
Public < E, N > void showArray(E x, N y) {
System.out.println(x);
System.out.println(y);
}
Public static void main(String[] args) {
test obj = new test();
obj.showArray("John Doe", 43);
}
}
Output:
John Doe
43
Java example to illustrate the use of Java Generics
package com.dataflair.javagenerics;
import java.io.*;
import java.util.*;
class GenericClass<T>
{
//This is a generic class definition. The type is T as mentioned.
GenericClass()
{
System.out.println("The generic class is declared now. You can use it well");
}
public void methodgeneric(T obj)
{
System.out.println("The type of the object that this class now contains is
"+obj.getClass().getSimpleName());
}
}
public class GenericsExample {
public static void main(String[] args) {
GenericClass<Integer> test=new GenericClass<>();
Integer a=5;
test.methodgeneric(a);
//Now we use the same class but with a different datatype.
GenericClass<String> teststring = new GenericClass<>();
String s="DataFlair is the best";
teststring.methodgeneric(s);
}
}
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

Output
The generic class is declared now. You can use it well
The type of the object that this class now contains is Integer
The generic class is declared now. You can use it well
The type of the object that this class now contains is String
If you observe carefully, we set the value of the same class with different datatypes. That is the power
of generics.
It allows you to work with different datatypes without worrying about the repercussions and different
rules of different data types.
Now let us see what the program is doing step by step.
● As soon as the main function calls the generic type object the constructor gets called and you
can see the line “The generic class is declared now. You can use it well”
● Now, as the class is generic in nature, it allows the Integer type object passed to its methods
and prints the class name.
● You can easily identify the class name and the type of the variable passed to the method by
the .getClass() method. Simple!
● Now we pass a different datatype but thanks to generics the method behaves the same way!

Generic Interface

An interface in Java refers to the abstract data types. They allow Java collections to be manipulated
independently from the details of their representation. Also, they form a hierarchy in object-oriented
programming languages. Let’s understand how generic type can be applied to interfaces in Java.
Example
public class GenericInterfaceExample {
public static void main(String args[]) {
Integer intOfArray[] = { 3, 6, 2, 8, 6 };
Character charOfArray[] = { 'A', 'r', 'V', 'w' };
String strOfArray[] = {"abc", "xyz", "pqr"};
MinMaxImpl<Integer> intMinMax = new MinMaxImpl<Integer>(intOfArray);
MinMaxImpl<Character> charMinMax = new MinMaxImpl<Character>(charOfArray);
MinMaxImpl<String> strMinMax = new MinMaxImpl<String>(strOfArray);
System.out.println("Max value in intOfArray: " + intMinMax.max());
System.out.println("Min value in intOfArray: " + intMinMax.min());
System.out.println("Max value in charOfArray: " + charMinMax.max());
System.out.println("Min value in charOfArray: " + charMinMax.min());
System.out.println("Max value in strOfArray: " + strMinMax.max());
System.out.println("Min value in strOfArray: " + strMinMax.min());
}
}
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
class MinMaxImpl<T extends Comparable<T>> implements MinMax<T> {
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

T[] vals;
MinMaxImpl(T[] o) {
vals = o;
}
public T min() {
T v = vals[0];
for (int i = 1; i < vals.length; i++) {
if (vals[i].compareTo(v) < 0) {
v = vals[i];
}
}
return v;
}
public T max() {
T v = vals[0];
for (int i = 1; i < vals.length; i++) {
if (vals[i].compareTo(v) > 0) {
v = vals[i];
}
}
return v;
}
}
Output
Max value in intOfArray: 8
Min value in intOfArray: 2
Max value in charOfArray: w
Min value in charOfArray: A
Max value in strOfArray: xyz
Min value in strOfArray: abc

Generic Constructor

A constructor can be generic, even if its class is not. A generic constructor is a constructor that has at
least one parameter of a generic type.
Example
public class Pair<T> {
private T first;
private T second;

public Pair() { first = null; second = null; }


public Pair(T firstItem, T secondItem) {
first = firstItem;
second = secondItem;
}
public String toString() {
return "(" + first + ", " + second + ")";
}
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

}
However, when you instantiate a generic class, you do specify the type in angular brackets when
writing the constructor name.
Pair<String> aPair = new Pair<String>("Happy", "Day"); // Create a pair of String object
Pair<Integer> bPair = new Pair<Integer>(2, 3); // Create a pair of Integer objects

Bounded Types
When you want to specify a particular type which is a subclass of a particular class you can use
Bounded Types. Bounded types allow you to restrict the data type of the collection. For example, if
you write a generic with the extends keyword then you can use bounded types.
E.g.: <T extends A>
If A is Number class then you can use all types of data which are of type Integer, Float, Double, etc.
Java program to illustrate bounded types in Java:
package com.dataflair.javagenerics;
class GenericTypeClass<T extends Number>
{
//This is a class where you can only use generic objects of classes
//which are a subclass of Number that is Integer, Float etc.
GenericTypeClass(T obj)
{
System.out.println(obj.getClass().getName());
}
}
public class Simple{
public static void main(String[]args)
{
Integer a = 10;
GenericTypeClass<Integer> obj = new GenericTypeClass<>(a);
String s="DataFlair";
//GenericTypeClass<String> obj2=new GenericTypeClass<>(a);
}
}
Output
java.lang.Integer
If you try to remove the commented line the compiler will throw an error because the String class
does not extend the Number class.

Wildcards
With wildcard, we can further enhance the usage of generics. We use a wildcard when we want to
make a method or class that can accept any kind of data or collection or when we want to impose
some restrictions or relaxation on a variable.
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

From the syntax, it’s easy enough to guess that "? extends T" means that there's a class that extends
the generic type T, but what is "? extends T "? Let’s answer this question with a code-driven
explanation.
Let’s suppose we’re writing a staff management application. We’ve got a Person class in our domain,
and it has two subclasses: an Employee and a Partner. One common operation you might wish to
perform is to save these objects into a database, and maybe write a method like this:
public void saveAll(final List<Person> people)
{
// Saves people into a database ...
}
What could go wrong with that? It’s so nice and simple, and we can use it like this:
List<People> people = new ArrayList<>();
people.add(donDraper);
people.add(peggyOlson);
saver.saveAll(people);
But wait. Let’s step back for a minute. We actually want to be able to save more than just lists of
people. We have Employees and Partners as well, and we want to be able to save lists of each. If we
try to write this code, we get a compile error on the line highlighted in red.:
List<Partner> people = new ArrayList<>();
people.add(donDraper);
people.add(bertCooper);
saver.saveAll(people);
Wildcards let us increase the flexibility of our generic type parameters by allowing us to pass in
subclasses and superclasses. You can spot them in code thanks to the way they look (? extends Foo
or ? super Bar). We could change the original method’s signature like this:
public void saveAll(final List<? extends Person> people)
{
// Saves people into a database ...
}
And now we can pass in variables that have types like List<Partner> or List<Employee>, as well as
List<Person> as an argument to our saveAll method. Problem solved! It’s also worth noting that
extends doesn’t just allow us to use subclasses of a class, but also implementers of an interface as
well.

Upper-bound Wildcards

It provides the freedom to the variable by either making it a specific type or subtype of the specific
type. In Java, it is declared by using the? keyword followed by the extend keyword. Extend keyword
is used to provide access to the subtypes of the specific type to the methods. Example list<? extends
Number> can be used to extend the type Number along with its subtype (Integer, Double etc.)
whereas list<Numbers> restrict user with a list of type number only. Observe the below code for
better understanding.
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

import java.util.Array;
import java.util.List;
public class UpperBoundWildcard {
private static Double SumOfElements(ArrayList < ? extends Number > num) {
double sum = 0.0;
for (Number n: num) {
sum = sum + n.doubleValue();
}
return sum;
}
public static void main(String[] args) {

List < Integer > ListOfIntegres = Arrays.asList(10, 20, 30);


System.out.println("The sum of the Integer list is = " + SumOfElements(ListOfInteger));
List < Double > ListOfDecimals = Arrays.asList(100.0, 200.0, 300.0);
System.out.println("The sum of the Double list is = " + SumOfElements(ListOfDecimals));
}
}
Output
The sum of the Integer list is = 60.0
The sum of the Double list is = 600.0
In the above code, a list of integer and list of double is executed without any error.

Unbounded Wildcards

Unbounded wild cards are used when we don’t know what type of list will come as input. In that case,
we make our method using list<?> which means that list can be of any type. We use it when we want
our method independent from parameter type. Example:
import java.util.Arrays;
import java.util.List;
public class UnboundedWildcard {
public static void show(List < ? > list) {
for (Object o: list) {
System.out.println(o);
}
}
public static void main(String[] args) {
List < Integer > ListOfIntegers = Arrays.asList(5, 10, 15);
System.out.println("List of Integer values-");
show(ListOfIntegers);
List < String > ListOfString = Arrays.asList("Virat", "Dhoni", "Dravid");
System.out.println("List of String values");
show(ListOfString);
}
}
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

Output
List of Integer values
5
10
15
List of String values
Virat
Dhoni
Dravid
The above code worked well for both types of lists i.e. integer and string. This is the advantage of
unbounded wildcard.

Lower-bound Wildcards

We use lower bound wildcards when we want to work on a specific type or superclass of that type like
integers and its superclass numbers. It is used by declaring wildcard symbol ? followed by the super
keyword. Consider the following example:
import java.util.Arrays;
import java.util.List;
public class LowerBoundWildcard {
public static void show(List < ? super Integer > list) {
for (Object n: list) {
System.out.println(n);
}
}
public static void main(String[] args) {
List < Integer > ListOfIntegres = Arrays.asList(10, 20, 30);
System.out.println("Showing the Integer values");
show(ListOfIntegres);
List < Number > ListOfNumbers = Arrays.asList(100.0, 200.0, 300.0);
System.out.println("Showing the Number values");
show(ListOfNumbers);
}
}
Output
Showing the Integer values
10
20
30
Showing the Number values
100.0
200.0
300.0
In the above code, we declared the list type be integers but by using the super keyword we made the
method acceptable for superclass of integers. That’s why we were able to print double values too
because superclass of integers i.e., numbers contains double class.
Object Oriented Programming
BS(SE) 2021
CSS 1042
Department of CS and SE

Exercises
1. Given the following classes:
class Shape { /* ... */ }
class Circle extends Shape { /* ... */ }
class Rectangle extends Shape { /* ... */ }

class Node<T> { /* ... */ }


Will the following code compile? If not, why?
Node<Circle> nc = new Node<>();
Node<Shape> ns = nc;

2. Consider the following code, where the 'printarray()' method is used to print out arrays of
different types:
Integer [] intArry = {1, 2, 3, 4, 5 };
Double [] doubArry = {1.1, 2.2, 3.3, 4.4};
Character [] charArray = {'H','E','L', 'L', 'O' };
String [] strArray = {“once”, “upon”, “a”, “time” };
printarray(intArry);
printarray(doubArry);
printarray(charArray);
printarray(strArray);
Write a JAVA program with a main method that includes the example code, above. Implement
the static printarray() method using Generic programming technique so that you have a single
method supporting all the types and maintain type safety.

3. Design a class that acts as a library for the following kinds of media: book, video, and newspaper.
Provide one version of the class that uses generics and one that does not.

You might also like