Java Generics Interview Questions and Answers

Java generics interview questions covering why generics are needed, type argument inference, generic methods, raw types, and common compile-time pitfalls.

Java Generics

Module: Generics and Collections
Topic: Java Generics


📋 Table of Contents


🔹 Q2: Why do you need generics?

Answer:

Generics was introduced in JDK 5.0, and allows you to abstract over types. Without generics, you could put heterogeneous objects into a collection. This can encourage developers to write programs that are harder to read and maintain. For example,List myList = new ArrayList ( ); //in Java 6 and 7 List myList = new ArrayList <>(); // In Java 8 can use empty <> List myList = new ArrayList ( ); List list = new ArrayList ( ); ist.add(new Integer ( )); ist.add(“A String ”);

As demonstrated above, without generics you can add any type of object to a collection. This means you would not only have to use “instanceof” operator, but also have to explicitly cast any objects returned from this list. The code is also less readable. The following code with generics is not only more readable, but also throws a compile time error if you try to add an Integer object to list1 or a String object to list2.


🔹 Q3: What are the differences among?

– Raw or plain old collection type e.g. Collection – Collection of unknown e.g. Collection<?> – Collection of type object e.g. Collection

Answer:

  1. The plain old Collection : is a heterogeneous mixture or a mixed bag that contains elements of all types, for example Integer, String, Fruit, V egetable, etc.
  2. The Collection : is also a heterogeneous mixture like the plain old Collection, but not the same and can be more restrictive than a plain old Collection discussed above. It is incorrect to think of this as the super type for a collection of any object types. Unlike an Object class is a super type for all objects like String, Integer, Fruit, etc, List is not a super type for List, List, List, etc. So it is illegal to do the following:ist.add(new Mango ( )); List list1 = new ArrayList ( ); List list2 = new ArrayList ( ); List list = new ArrayList ( );//illegal

Though Integer is a subtype of Object, List is not a subtype of List because List of Objects is a bigger set comprising of elements of various types like Strings, Integers, Fruits, etc. A List of Integer should only contain Integers, hence the above line is illegal. If the above line was legal, then you can end up adding objects of any type to the list, violating the purpose of generics. 3) The Collection is the super type for all generic collection as Object[ ] is the super type for all arrays. Number class hierachy


🔹 Q4: How will you go about deciding which of the following to use?

List<? extends Number > list = new ArrayList ( ); //legal

Answer:

Many developers struggle with the wild cards. Here is the guide:

  1. Use the ? extends wildcard if you need to retrieve object from a data structure. That is read only. You can’ t add elements to the collection.
  2. Use the ? super wildcard if you need to put objects in a data structure.
  3. If you need to do both read and add elements, don’t use any wildcard .

List list2 = new ArrayList ( ); System.out.println (list1.getClass ( ) == list2.getClass ( )); f(list1 instanceof List) //illegal List list = new ArrayList ( );

Answer:

It is Illegal because Unlike an Object class is a super type for all objects like String, Integer, Fruit, etc, List&l;tObject> is not a super type for List, List, List, etc. List is almost read only allowing only removce( ) and clear ( ) operations. The Collection<?> can only be used as a reference type, and you cannot instantiate it.


🔹 Q8: What do you understand by the term type argument inference?

Answer:

The type inference happens when the compiler can deduce the type arguments of a generic type or method from a given context information. There are 2 situations in which the type argument inference is attempted during compile-time.

  1. When an object of a generic type is created as demonstrated in the MyGenericClass.
  2. When a generic method is invoked. For example,} public static void main (String [ ] args) { MyGenericClass val1 = new MyGenericClass (Integer .valueOf (37)); //auto-box MyGenericClass val2 = new MyGenericClass (Long .valueOf (250L )); //auto-box long result = ((Integer )val1.getObjT ype( )).longV alue( ) + ((Long )val2.getObjT ype( )).longV alue( ); System.out.println (result ); } /T is inferred as an Integer MyGenericClass val1 = new MyGenericClass (37); /T is inferred as a Long MyGenericClass val2 = new MyGenericClass (250L ); mport java.util.ArrayList ;

mport java.util.List; public class MyBasket { /**

  • The 'src' is the inferred type T or its sub type and the 'dest' is the
  • inferred type T or its super type. */ public static void copy (List<? extends T> src, List<? super T> dest) { for (T obj : src) { dest.add(obj); } } public static void main (String [] args) { List orangeBasket = new ArrayList (10); List mangoBasket = new ArrayList (10); orangeBasket .add(new Orange ()); mangoBasket .add(new Mango ()); List fruitBasket = new ArrayList (10); List orangeBasket2 = new ArrayList (10); orangeBasket2 .add(new Orange ()); List mangoBasket2 = new ArrayList (10); mangoBasket2 .add(new Mango ()); List fruitBasket2 = new ArrayList (10); fruitBasket2 .add(new Mango ()); MyBasket .copy (orangeBasket2, orangeBasket ); // T is an Orange MyBasket .copy (mangoBasket2, mangoBasket ); // T is a Mango MyBasket . copy (orangeBasket, fruitBasket ); // T is an Orange MyBasket . copy (mangoBasket, fruitBasket ); // T is a Mango MyBasket .copy (fruitBasket2, fruitBasket ); // T is a Fruit for (Fruit fruit : fruitBasket ) { fruit.peel(); } }

The copy(…) method ensures that fruits from a mixed fruit basket cannot be copied to a basket that only holds oranges or mangoes. But a mixed fruit basket allows fruits to be copied from any basket.


Answer:

It is not legal as new T( ) will cause a compile-time error. This is partially because there’ s no guarantee that the tar get class for raw type “T” has a constructor that takes zero parameters and partially due to type erasure where the raw type “T” does not have any way of knowing the type of object you want to construct at runtime.


🔹 Q10: Is it possible to generify methods in Java?

Answer:

Yes.public MyGenericClass ( ) { this.objType = new T( ); } mport java.util.ArrayList ; mport java.util.List; public class MyGenericMethod {

//Generified method public static void addV alue(T value, List list){//Line A list.add(value ); } public static void main (String [ ] args) { List listIntegers = new ArrayList ( ); Integer value1 = new Integer (37);

Note : If you had used the wildcard List<?> instead of List on line A, it would not have been possible to add elements. You will get a compile-time error. So how does the compiler know the type of “T”? It infers this from your use of the method. The generated class file looks pretty much the same as the source file without the and angle brackets


🔹 Q11: Does the following code snippet compile? What does it demonstrate?

Answer:

Yes, the above code snippet does compile. It demonstrates that the type parameter in the class name and the type parameter in the method are actually different parameters. The method signature, addV alue(value1, listIntegers ); //T is inferred as an Integer System.out.println ("listIntegers=" + listIntegers );

List listString = new ArrayList ( ); String value2 = "Test"; addV alue(value2, listString ); //T is inferred as a String System.out.println ("listString=" + listString ); } public class Generics4 {

public void doSomething (T data) { System.out.println (data); }

public static void main (String [ ] args) { Generics4 g4 = new Generics4 ( ); g4.doSomething (123); }

really means,


🔹 Q12: Can you identify any issues with the following code? public void doSomething (T data)

public void doSomething (Object data) mport java.util.ArrayList ; mport java.util.Iterator ; mport java.util.List; public class GenericsWithIterators { public static void main (String [ ] args) { List listIntegers = new ArrayList ( ); //1 listIntegers .add(5); //2 listIntegers .add(3); //3

Iterator it = listIntegers .listIterator ( ); //4

while (it.hasNext ( )){ //5 Integer i = it.next( ); //6 System.out.println (i); //7

Answer:

Line 4 will cause compile-time error on line 6 as the iterator is not generic. T o fix this, replace line 4 with: or add an explicit cast to line 6. The fix 1 is preferred. When you get an iterator, keyset, or values from a collection, assign it to an appropriate parametrized type as shown in fix 1. Have you completed this unit? Then mark this unit as completed. Mark as Completed « Previous Unit Next Unit » } } terator it = listIntegers .listIterator ( ); // fix 1 nteger i = (Integer ) it.next( );// fix 2


Source: Extracted from PDF Last Updated: 2026-06-03



💡 Key Takeaways

Review the questions above and ensure you understand:

  • Core concepts and their practical applications
  • Real-world scenarios and use cases
  • Best practices and common pitfalls

⬆ Back to Top

Was this guide helpful?

CodeWithVenu is free to read, with no paywall. If this guide saved you time or helped you prepare, a small voluntary contribution helps me write more practical tutorials, architecture guides, and interview-prep content.