Java Genrics is one of the most important features introduced in Java 5. If you have been working on Java Collections and with version 5 or higher, I am sure that you have used it. Generics in Java with collection classes is very easy but it provides a lot more features than just creating the type of collection. We will try to learn the features of generics in this article. Understanding generics can become confusing sometimes if we go with jargon words, so I would try to keep it simple and easy to understand. Show
We will look into below topics of generics in java.
1. Generics in JavaGenerics was added in Java 5 to provide compile-time type checking and removing risk of
Above code compiles fine but throws ClassCastException at runtime because we are trying to cast Object in the list to String whereas one of the element is of type Integer. After Java 5, we use collection classes like below.
Notice that at the time of list creation, we have specified that the type of elements in the list will be String. So if we try to add any other type of object in the list, the program will throw compile-time error. Also notice that in for loop, we don’t need typecasting of the element in the list, hence removing the ClassCastException at runtime. 2. Java Generic ClassWe can define our own classes with generics type. A generic type is a class or interface that is parameterized over types. We use angle brackets (<>) to specify the type parameter. To understand the benefit, let’s say we have a simple class as:
Notice that while using this class, we have to use type casting and it can produce ClassCastException at runtime. Now we will use java generic class to rewrite the same class as shown below.
Notice the use of GenericsType class in the main method. We don’t need to do type-casting and we can remove ClassCastException at runtime. If we don’t provide the
type at the time of creation, the compiler will produce a warning that “GenericsType is a raw type. References to generic type GenericsType<T> should be parameterized”. When we don’t provide the type, the type becomes Tip: We can use Also notice that it supports java autoboxing. 3. Java Generic InterfaceComparable interface is a great example of Generics in interfaces and it’s written as:
In similar
way, we can create generic interfaces in java. We can also have multiple type parameters as in Map interface. Again we can provide parameterized value to a parameterized type also, for example 4. Java Generic TypeJava Generic Type Naming convention helps us understanding code easily and having a naming convention is one of the best practices of Java programming language. So generics also comes with its own naming conventions. Usually, type parameter names are single, uppercase letters to make it easily distinguishable from java variables. The most commonly used type parameter names are:
5. Java Generic MethodSometimes we don’t want the whole class to be parameterized, in that case, we can create java generics method. Since the constructor is a special kind of method, we can use generics type in constructors too. Here is a class showing an example of a java generic method.
Notice the isEqual method signature showing syntax to use generics type in methods. Also, notice how to use these methods in our java program. We can specify type while calling these methods or we can invoke them like a normal method. Java compiler is smart enough to determine the type of variable to be used, this facility is called type inference. 6. Java Generics Bounded Type ParametersSuppose we want to restrict the type of objects that can be used in the parameterized type, for example in a method that compares two objects and we want to make sure that the accepted objects are Comparables. To declare a bounded type parameter, list the type parameter’s name, followed by the extends keyword, followed by its upper bound, similar like below method.
The invocation of these methods is similar to unbounded method except that if we will try to use any class that is not Comparable, it will throw compile-time error. Bounded type parameters can be used with methods as well as classes and interfaces. Java Generics supports multiple bounds also, i.e <T extends A & B & C>. In this case, A can be an interface or class. If A is class then B and C should be an interface. We can’t have more than one class in multiple bounds. 7. Java Generics and InheritanceWe know that Java inheritance allows us to assign a variable A to another variable B if A is subclass of B. So we might think that any generic type of A can be assigned to generic type of B, but it’s not the case. Let’s see this with a simple program.
We are not allowed to assign MyClass<String> variable to MyClass<Object> variable because they are not related, in fact MyClass<T> parent is Object. 8. Java Generic Classes and SubtypingWe can subtype a generic class or interface by extending or implementing it. The relationship between the type parameters of one class or interface and the type parameters of another are determined by the extends and implements clauses. For example, ArrayList<E> implements List<E> that extends Collection<E>, so ArrayList<String> is a subtype of List<String> and List<String> is subtype of Collection<String>. The subtyping relationship is preserved as long as we don’t change the type argument, below shows an example of multiple type parameters.
The subtypes of List<String> can be MyList<String,Object>, MyList<String,Integer> and so on. 9. Java Generics WildcardsQuestion mark (?) is the wildcard in generics and represent an unknown type. The wildcard can be used as the type of a parameter, field, or local variable and sometimes as a return type. We can’t use wildcards while invoking a generic method or instantiating a generic class. In the following sections, we will learn about upper bounded wildcards, lower bounded wildcards, and wildcard capture. 9.1) Java Generics Upper Bounded WildcardUpper bounded wildcards are used to relax the restriction on the type of variable in a method. Suppose we want to write a method that will return the sum of numbers in the list, so our implementation will be something like this.
Now the problem with above implementation is that it won’t work with List of Integers or Doubles because we know that List<Integer> and List<Double> are not related, this is when an upper bounded wildcard is helpful. We use generics wildcard with extends keyword and the upper bound class or interface that will allow us to pass argument of upper bound or it’s subclasses types. The above implementation can be modified like the below program.
It’s similar like writing our code in terms of interface, in the above method we can use all the methods of upper bound class Number. Note that with upper bounded list, we are not allowed to add any object to the list except null. If we will try to add an element to the list inside the sum method, the program won’t compile. 9.2) Java Generics Unbounded WildcardSometimes we have a situation where we want our generic method to be working with all types, in this case, an unbounded wildcard can be used. Its same as using <? extends Object>.
We can provide List<String> or List<Integer> or any other type of Object list argument to the printData method. Similar to upper bound list, we are not allowed to add anything to the list. 9.3) Java Generics Lower bounded WildcardSuppose we want to add Integers to a list of integers in a method, we can keep the argument type as List<Integer> but it will be tied up with Integers whereas List<Number> and List<Object> can also hold integers, so we can use a lower bound wildcard to achieve this. We use generics wildcard (?) with super keyword and lower bound class to achieve this. We can pass lower bound or any supertype of lower bound as an argument, in this case, java compiler allows to add lower bound object types to the list.
10. Subtyping using Generics Wildcard
11. Java Generics Type ErasureGenerics in Java was added to provide type-checking at compile time and it has no use at run time, so java compiler uses type erasure feature to remove all the generics type checking code in byte code and insert type-casting if necessary. Type erasure ensures that no new classes are created for parameterized types; consequently, generics incur no runtime overhead. For example, if we have a generic class like below;
The Java compiler replaces the bounded type parameter T with the first bound interface, Comparable, as below code:
12. Generics FAQs12.1) Why do we use Generics in Java?Generics provide strong compile-time type checking and reduces risk of ClassCastException and explicit casting of objects. 12.2) What is T in Generics?We use <T> to create a generic class, interface, and method. The T is replaced with the actual type when we use it. 12.3) How does Generics work in Java?Generic code ensures type safety. The compiler uses type-erasure to remove all type parameters at the compile time to reduce the overload at runtime. 13. Generics in Java - Further Readings
That’s all for generics in java, java generics is a really vast topic and requires a lot of time to understand and use it effectively. This post here is an attempt to provide basic details of generics and how can we use it to extend our program with type-safety. When method in a subclass has the same name and type signature as a method in the superclass that the method in subclass the method in superclass?Explanation: When a method in a subclass has the same name and type signatures as a method in the superclass, then the method in the subclass overrides the method in the superclass.
When a method in a subclass has the same name and type signature as a method in its superWhen a method in a subclass has the same name, same parameters or signature, and same return type(or sub-type) as a method in its super-class, then the method in the subclass is said to override the method in the super-class. Method overriding is one of the way by which java achieve Run Time Polymorphism.
Can a subclass have a method with the same name and the same signature as its superclass?If your subclass defines a method with the same name and signature as a method in its superclass, the method in the subclass overrides the one in the superclass. Thus, the subclass does not inherit the method from its superclass.
What is the process of defining a method in a subclass having same name and type?If subclass (child class) has the same method as declared in the parent class, it is known as method overriding in Java.
|