0% found this document useful (0 votes)
2 views

DownloadClassSessionFile (71)

Generics in Java allow types to be parameters for classes, interfaces, and methods, enhancing code stability by enabling compile-time bug detection and eliminating the need for type casting. They facilitate the creation of type-safe and reusable code, allowing programmers to implement generic algorithms that work across different types. The document also discusses raw types, generic methods, and provides examples of how to define and use generics effectively.

Uploaded by

KARZAN -t
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

DownloadClassSessionFile (71)

Generics in Java allow types to be parameters for classes, interfaces, and methods, enhancing code stability by enabling compile-time bug detection and eliminating the need for type casting. They facilitate the creation of type-safe and reusable code, allowing programmers to implement generic algorithms that work across different types. The document also discusses raw types, generic methods, and provides examples of how to define and use generics effectively.

Uploaded by

KARZAN -t
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Generics

In any nontrivial software project, bugs are simply a fact of life. Careful
planning, programming, and testing can help reduce their pervasiveness,
but somehow, somewhere, they'll always find a way to creep into your
code. This becomes especially apparent as new features are introduced
and your code base grows in size and complexity.

Fortunately, some bugs are easier to detect than others. Compile-time


bugs, for example, can be detected early on; you can use the compiler's
error messages to figure out what the problem is and fix it, right then and
there. Runtime bugs, however, can be much more problematic; they don't
always surface immediately, and when they do, it may be at a point in the
program that is far removed from the actual cause of the problem.
Generics add stability to your code by making more of your bugs
detectable at compile time.

Object Oriented Programming in Java 1


Generics
Why we use Generics?
Generics enable types to be parameters when defining classes, interfaces
and methods. Much like the more familiar formal parameters used in
method declarations, type parameters provide a way for you to re-use the
same code with different inputs.
The difference is that the inputs to formal parameters are values, while the
inputs to type parameters are types. Code that uses generics has many
benefits over non-generic code:

1- Stronger type checks at compile time: A Java compiler applies strong


type checking to generic code and issues errors if the code violates type
safety. Fixing compile-time errors is easier than fixing runtime errors, which
can be difficult to find.

Object Oriented Programming in Java 2


Generics
Stack stack = new Stack();
stack.push(4);
stack.push(5);
stack.push("6");
System.out.println(stack.pop() + 5);
System.out.println(stack.pop() + 5);
System.out.println(stack.pop() + 5);

2- Elimination of casts: The following code snippet without generics


requires casting:
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);

Object Oriented Programming in Java 3


Generics
When re-written to use generics, the code does not require casting:
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0); // no cast

3- Enabling programmers to implement generic algorithms: By using


generics, programmers can implement generic algorithms that work on
collections of different types, can be customized, and are type safe and
easier to read.

The old method of creating a class without generic was to implement it with
Object class.

Object Oriented Programming in Java 4


Generics
public class Box
{
private Object object;
public void set(Object object)
{
this.object = object;
}
public Object get()
{
return object; }
}
Since its methods accept or return an Object, you are free to pass in
whatever you want, provided that it is not one of the primitive types.

Object Oriented Programming in Java 5


Generics
There is no way to verify, at compile time, how the class is used. One part
of the code may place an Integer in the box and expect to get Integers out
of it, while another part of the code may mistakenly pass in a String,
resulting in a runtime error.

A generic class is defined with the following format:


class name <T1, T2, ..., Tn> { /* … */}

The type parameter section, delimited by angle brackets (<>), follows the
class name.
It specifies the type parameters (also called type variables) T1, T2, ..., and
Tn.

Object Oriented Programming in Java 6


Generics
To update the Box class to use generics, you create a generic type
declaration by changing the code "public class Box" to "public class
Box<T>". This introduces the type variable, T, that can be used anywhere
inside the class.
With this change, the Box class becomes:
public class Box <T>
{
// T stands for "Type"
private T t;
public void set(T t)
{ this.t = t; }
public T get() { return t; }
}

Object Oriented Programming in Java 7


Generics
As you can see, all occurrences of Object are replaced by T. A type
variable can be any non-primitive type you specify: any class type, any
interface type, any array type, or even another type variable.
The same technique can be applied to create generic interfaces.

By convention, type parameter names are single uppercase letters. This


stands in sharp contrast to the variable naming conventions that you
already know about, and with good reason: Without this convention, it
would be difficult to tell the difference between a type variable and an
ordinary class or interface name.
The most commonly used type parameter names are:
E - Element (used extensively by the Java Collections Framework)
K – Key N – Number T - Type
V – Value S,U,V etc. - 2nd, 3rd, 4th types

Object Oriented Programming in Java 8


Generics
To reference the generic Box class from within your code, you must
perform a generic type invocation, which replaces T with some concrete
value, such as Integer:
Box<Integer> integerBox = new Box<Integer>(); //Or
Box<Integer> integerBox = new Box<>(); //The Diamond

You can think of a generic type invocation as an ordinary method


invocation, but instead of passing an argument to a method, you are
passing a type argument.

As mentioned previously, a generic class can have multiple type


parameters. For example, the generic OrderedPair class, which
implements the generic Pair interface:

Object Oriented Programming in Java 9


Generics
public interface Pair<K, V> {
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair<K, V>{
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}

Object Oriented Programming in Java 10


Generics
The following statements create two instantiations of the OrderedPair
class:
Pair<String, Integer> p1 = new OrderedPair<String,
Integer>("Even", 8);
Pair<String, String> p2 = new OrderedPair<String,
String>("hello", "world");

Raw Types
A raw type is the name of a generic class or interface without any type
arguments. For example, given the generic Box class:
public class Box<T>
{
public void set(T t) { /* ... */ }
}
Object Oriented Programming in Java 11
Generics
To create a parameterized type of Box<T>, you supply an actual type
argument for the formal type parameter T:
Box<Integer> intBox = new Box<>();
If the actual type argument is omitted, you create a raw type of Box<T>:
Box rawBox = new Box();

Therefore, Box is the raw type of the generic type Box<T>. However, a
non-generic class or interface type is not a raw type.
Raw types show up in legacy code because lots of API classes (such as
the Collections classes) were not generic prior to JDK 5.0.
When using raw types, you essentially get pre-generics behavior — a Box
gives you Objects.

Object Oriented Programming in Java 12


Generics
For backward compatibility, assigning a parameterized type to its raw type
is allowed:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox; // OK
But if you assign a raw type to a parameterized type, you get a warning:
Box rawBox = new Box(); // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox; // warning: unchecked
conversion
You also get a warning if you use a raw type to invoke generic methods
defined in the corresponding generic type:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8);//warning: unchecked invocation to set(T)

Object Oriented Programming in Java 13


Generics
Generic Methods
Generic methods are methods that introduce their own type parameters.
This is similar to declaring a generic type, but the type parameter's scope
is limited to the method where it is declared. Static and non-static generic
methods are allowed, as well as generic class constructors.

The syntax for a generic method includes a list of type parameters, inside
angle brackets, which appears before the method's return type. For static
generic methods, the type parameter section must appear before the
method's return type.

The Util class includes a generic method, compare, which compares two
Pair objects:

Object Oriented Programming in Java 14


Generics
public class Util
{
public static <K, V> boolean compare(Pair<K, V> p1,
Pair<K, V> p2)
{
return p1.getKey().equals(p2.getKey()) &&
p1.getValue().equals(p2.getValue());
}
}

public class Pair<K, V> {


private K key;
private V value;

Object Oriented Programming in Java 15


Generics
public Pair(K key, V value) {
this.key = key;
this.value = value;}
public void setKey(K key) { this.key = key; }
public void setValue(V value){ this.value = value; }
public K getKey() { return key; }
public V getValue() { return value; }
}

The complete syntax for invoking this method would be:


Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, “orange");
boolean same = Util.<Integer, String>compare(p1, p2);

Object Oriented Programming in Java 16


Generics
The type has been explicitly provided, as shown in bold. Generally, this can
be left out and the compiler will infer the type that is needed:
Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);
This feature, known as type inference, allows you to invoke a generic
method as an ordinary method, without specifying a type between angle
brackets.

Object Oriented Programming in Java 17

You might also like