| Start |
|---|
| Creating a Generic Class Generics (opens new window) enable classes, interfaces, and methods to take other classes and interfaces as type parameters. This example uses generic class To instantiate this class, provide a type argument in place of The type argument can be any reference type, including arrays and other generic types: In Java SE 7 and later, the type argument can be replaced with an empty set of type arguments ( Unlike other identifiers, type parameters have no naming constraints. However their names are commonly the first letter of their purpose in upper case. (This is true even throughout the official JavaDocs.) Extending a generic class
The following is the usage: Notice that in the It is also possible to instantiate with anonymous inner class with an empty curly braces ( Note that using the diamond with anonymous inner classes is not allowed. (opens new window) Multiple type parametersJava provides the ability to use more than one type parameter in a generic class or interface. Multiple type parameters can be used in a class or interface by placing a comma-separated list of types between the angle brackets. Example: The usage can be done as below: |
Deciding between T, ? super T, and ? extends T The syntax for Java generics bounded wildcards, representing the unknown type by As a rule of thumb, you should use
Using The compiler will now be able to detect certain bad usage: Choosing the right If it is not easy to understand, please remember PECS rule: Producer uses "Extends" and Consumer uses "Super". (Producer has only write access, and Consumer has only read access) |
| The Diamond Java 7 introduced the Diamond (opens new window)1 to remove some boiler-plate around generic class instantiation. With Java 7+ you can write: Where you had to write in previous versions, this: One limitation is for Anonymous Classes (opens new window), where you still must provide the type parameter in the instantiation: Although using the diamond with Anonymous Inner Classes (opens new window) is not supported in Java 7 and 8, it will be included as a new feature in Java 9 (opens new window). Footnote: 1 - Some people call the |
| Declaring a Generic Method Methods can also have generic (opens new window) type parameters. Notice that we don't have to pass an actual type argument to a generic method. The compiler infers the type argument for us, based on the target type (e.g. the variable we assign the result to), or on the types of the actual arguments. It will generally infer the most specific type argument that will make the call type-correct. Sometimes, albeit rarely, it can be necessary to override this type inference with explicit type arguments: It's necessary in this example because the compiler can't "look ahead" to see that |
| Requiring multiple upper bounds ("extends A & B") You can require a generic type to extend multiple upper bounds. Example: we want to sort a list of numbers but In this example Since multiple inheritance is not allowed, you can use at most one class as a bound and it must be the first listed. For example, |
| Benefits of Generic class and interface Code that uses generics has many benefits over non-generic code. Below are the main benefits Stronger type checks at compile timeA 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. Elimination of castsThe following code snippet without generics requires casting: When re-written to use generics, the code does not require casting: Enabling programmers to implement generic algorithmsBy 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. |
| Instantiating a generic type Due to type erasure the following will not work: The type WorkaroundsWhich throws exceptions, since there is no way to know if the passed class has an accessible default constructor. |
| Obtain class that satisfies generic parameter at runtime Many unbound generic parameters, like those used in a static method, cannot be recovered at runtime (see Other Threads on Erasure). However there is a common strategy employed for accessing the type satisfying a generic parameter on a class at runtime. This allows for generic code that depends on access to type without having to thread type information through every call. Background Generic parameterization on a class can be inspected by creating an anonymous inner class. This class will capture the type information. In general this mechanism is referred to as super type tokens, which are detailed in Neal Gafter's blog post (opens new window). Implementations Three common implementations in Java are:
Example usage |
| Creating a Bounded Generic Class You can restrict the valid types used in a generic class by bounding that type in the class definition. Given the following simple type hierarchy: Without bounded generics, we cannot make a container class that is both generic and knows that each element is an animal: With generic bound in class definition, this is now possible. This also restricts the valid instantiations of the generic type: |
| Referring to the declared generic type within its own declaration How do you go about using an instance of a (possibly further) inherited generic type within a method declaration in the generic type itself being declared? This is one of the problems you will face when you dig a bit deeper into generics, but still a fairly common one. Assume we have a The problem can be solved by adding a generic type parameter referring back to and extending the type being declared (applied to an interface here, but the same stands for classes): Here At this moment even an IDE will implement the above interface with correct types in place, which, after a bit of content filling may look like this: As you can see the The pattern can be further nested if required. |
| Binding generic parameter to more than 1 type Generic parameters can also be bound to more than one type using the Let's say you want to create a class whose Generic type should implement both Now, the The class methods can choose to infer generic type arguments as either Note:You cannot bind the generic parameter to either of the type using OR ( |
| Using Generics to auto-cast With generics, it's possible to return whatever the caller expects: The method will compile with a warning. The code is actually more safe than it looks because the Java runtime will do a cast when you use it: It's less safe when you use generic types: Here, the cast will work when the returned type is any kind of To work around this problem, you can create an API which uses typed keys: along with this With this approach, you can't put the wrong type into the map, so the result will always be correct (unless you accidentally create two keys with the same name but different types). Related: |
| Use of instanceof with Generics Using generics to define the type in instanceof Consider the following generic class This will always give a Compilation error because as soon as the compiler compiles the Java source into Java bytecode it applies a process known as type erasure, which converts all generic code into non-generic code, making impossible to distinguish among T types at runtime. The type used with The following class represents what two different classes of Since types are gone, it's not possible for the JVM to know which type is Exception to the previous rule You can always use unbounded wildcard (?) for specifying a type in the This can be useful to evaluate whether an instance In fact, unbounded wildcard is considered a reifiable type. Using a generic instance with instanceof The other side of the coin is that using an instance because after the type erasure the class will look like the following: Since, even if the type erasure happen anyway, now the JVM can distinguish among different types in memory, even if they use the same reference type ( |
| Different ways for implementing a Generic Interface (or extending a Generic Class) Suppose the following generic interface has been declared: Below are listed the possible ways to implement it. Non-generic class implementation with a specific type Choose a specific type to replace the formal type parameter This class only deals with Generic class implementation Declare another generic interface with the formal type parameter Note that a different formal type parameter may have been used, as follows: Raw type class implementation Declare a non-generic class which implements This way is not recommended, since it is not 100% safe at runtime because it mixes up raw type (of the subclass) with generics (of the interface) and it is also confusing. Modern Java compilers will raise a warning with this kind of implementation, nevertheless the code - for compatibility reasons with older JVM (1.4 or earlier) - will compile. All the ways listed above are also allowed when using a generic class as a supertype instead of a generic interface. Syntax
RemarksGenerics are implemented in Java through Type erasure, which means that during runtime the Type information specified in the instantiation of a generic class is not available. For example, the statement This also means that when casting to a generic type (e.g.: |
Read Article
https://develop.horje.com/learn/1434/reference