What are Java generics?
Java Generics, sometimes used as a plural noun (generics) and sometimes as a singular noun (Generics), is a language feature of Java that allows for the definition and use of generic types and methods. | |
'Java Generics' is a technical term denoting a set of language features related to the definition and use of generic types and methods . Generic types or methods differ from regular types and methods in that they have type parameters. Examples of generic types can be found in the Collections framework of the J2SE 5.0 platform libraries. A class like LinkedList<E> is a generic type. It has a type parameter E that represents the type of the elements stored in the list. Instead of just using a LinkedList , not saying anything about the type of elements the list contains, we can use a LinkedList<String> or a LinkedList<Integer> , thereby specifying that we mean a list of strings or integral values respectively. Generic types are instantiated to form parameterized types by providing actual type arguments that replace the formal type parameters. A class likeLinkedList<E> is a generic type, that has a type parameter E . Instantiations, such as LinkedList<String> or a LinkedList<Integer> , are called parameterized types, and String and Integer are the respective actual type arguments. | |
What is the primary purpose of Java generics? |
Java generics were invented primarily for implementation of generic collections. | |
The need for generic types stems mainly from the implementation and use of collections, like the ones in the Java Collections framework. Programmers often want to specify that a collection contains elements of a certain type, such as a list of integral values or a list of strings. The Collections framework in non-generic Java did not offer any homogenous collections of elements of the same type. Instead, all collections were holding Object references and for that reason they were potentially heterogenous, that is, a mix of objects of different types. This was also visible in the collection APIs: the non-generic collections accepted objects of arbitrary type for insertion into the collection and returned an Object reference when an element was retrieved from the collection (see packagejava.util in Java 1.4). In non-generic Java, homogenous collections of elements had required implementation of different classes, such as a class IntegerList and a class StringListfor holding integral values and strings respectively. Naturally, implementing a separate collection class for every conceivable element type is neither feasible nor desirable. A more reasonable goal is to have a single implementation of the collection class and use it to hold elements of different types. In other words, rather than implementing a class IntegerList and StringList , we want to have one generic implementation List that can be easily used in either case, as well as in other unforeseen cases. This is what generics are for: the implementation of one generic class can be instantiated for a variety of types. There is one generic class List in the generic collections framework (see package java.util in Java 5.0). It permits specification of List<Integer> , List<String> , etc. each of which is a homogenous collection of integral values, strings, etc. In generic Java, the generic class List is a so-called generic class that has a type parameter. Uses such asList<Integer> and List<String> are so-called parameterized types . They are instantiations of the generic class, where the type parameter is replaced by the concrete type arguments Integer and String . The use of the Java generics language features were initially motivated by the need to have a mechanism for efficient implementation of homogenous collections, but the language feature is not restricted to collections. The J2SE 5.0 platform libraries contains numerous examples of generic types and methods that have nothing to do with collections. Examples are the weak and soft references in package java.lang.ref , which are special purpose references to objects of a particular type represented by a type parameter. Or the interface Callable in package java.util.concurrent , which represents a task and has a callmethod that returns a result of a particular type represented by a type parameter. Even class Class in package java.lang is a generic class since Java 5.0, whose type parameter denotes the type that the Class object represents. |
What is the benefit of using Java generics?
Early error detection at compile time. | |
Using a parameterized type such as LinkedList<String> , instead of LinkedList , enables the compiler to perform more type checks and requires fewer dynamic casts. This way errors are detected earlier, in the sense that they are reported at compile-time by means of a compiler error message rather than at runtime by means of an exception. Consider the example of a LinkedList<String> . The type LinkedList<String> expresses that the list is a homogenous list of elements of type String . Based on the stronger information the compiler performs type checks in order to ensure that a LinkedList<String> contains only strings as elements. Any attempt to add an alien element is rejected with a compiler error message. Example (using a parameterized type): LinkedList<String> list = new LinkedList<String>();Using a plain LinkedList , the compiler had not issued any message and both elements would have been added to the list. This is because the non-parameterizedLinkedList does not mandate that all elements must be of the same or any particular type. A non-parameterized list is a sequence of elements of type Object and hence arbitrary. Same example (using a non-parameterized type): LinkedList list = new LinkedList(); Since it is ensured that a LinkedList<String> contains strings it is not necessary to cast an element retrieved from the list to type String . Example (using a parameterized type): LinkedList<String> list = new LinkedList<String>();Using a plain LinkedList , there is no knowledge and no guarantee regarding the type of the element retrieved. All retrieval methods return an Object reference, which must be cast down to the actual type of the element retrieved. Same example (using a non-parameterized type): LinkedList list = new LinkedList();The cast would fail at runtime with a ClassCastException in case the element retrieved is not of type String . This type of runtime failure cannot happen with a parameterized list because the compiler already prevents insertion of an alien element into the sequence. | |
What does type-safety mean?
In Java, a program is considered type-safe if it compiles without errors and warnings and does not raise any unexpected ClassCastException s at runtime. | |
The idea is that a well-formed program enables the compiler to perform enough type checks based on static type information that no unexpected type error can occur at runtime. An unexpected type error in this sense is a ClassCastException being raised without any visible cast expression in the source code. |
No comments:
Post a Comment