This is one of the first interview questions asked on generics in any Java interview, mostly at beginners and intermediate level.
Those who are coming from prior to Java 5 background knows that how inconvenient it was to store object in Collection and then cast it back to correct Type before using it.
Generics prevents from those, it provides compile time type-safety and ensures that you only insert correct Type in collection and avoids ClassCastException in runtime.
This is related to previous generics interview questions, some time instead of asking what is bounded and unbounded wildcards interviewer present this question to gauge your understanding of generics.
Both of List declaration is example of bounded wildcards, List< ? extends T > will accept any List with Type extending T while List< ? super T > will accept any List with type super class of T.
For Example: List< ? extends Number > can accept List or List.
This is one of better interview question in Generics.
Generics is implemented using Type erasure, compiler erases all type related information during compile time and no type related information is available during runtime.
For example: List is represented by only List at runtime. This was done to ensure binary compatibility with the libraries which were developed prior to Java 5. You don't have access to Type argument at runtime and Generic type is translated to Raw type by compiler during runtime.
You can get a lot of follow up question based on this Generic interview question based upon your response. e.g. Why Generics is implemented using Type erasure or presenting some invalid generic code which results in compiler error.
This is another very popular Java interview questions on Generics.
Bounded Wildcards are those which impose bound on Type. There are two kinds of Bounded wildcards:
< ? extends T > which impose an upper bound by ensuring that type must be sub class of T
< ? super T > where its imposing lower bound by ensuring Type must be super class of T.
This Generic Type must be instantiated with Type within bound otherwise it will result in compilation error. On the other hand < ? > represent and unbounded type because < ? > can be replace with any Type.
This generic interview question in Java may look confusing to any one who is not very familiar with Generics as in fist glance it looks like String is object so List can be used where List< Object > is required but this is not true. It will result in compilation error. It does make sense if you go one step further because List< Object > can store any any thing including String, Integer etc but List can only store Strings.
List<Object> objectList;
List stringList;
objectList = stringList; // compilation error incompatible types
Writing generic method is not difficult, instead of using raw type you need to use Generic Type like T, E or K,V which are well known placeholders for Type, Element and Key, Value.
In simplest form a generic method would look like :
public V put(K key, V value){
return cache.put(key, value);
}
This is an extension of previous Java generics interview question. Instead of asking to write Generic method Interviewer may ask to write a type safe class using generics. Again key is instead of using raw types you need to used generic types and always use standard place holder used in JDK.
This is an exercise for anyone who like Coding in Java. One hint is that LinkedHashMap can be used implement fixed size LRU cache where one needs to remove eldest entry when Cache is full. LinkedHashMap provides a method called removeEldestEntry() which is called by put() and putAll() and can be used to instruct to remove eldest entry.
You are free to come up with your own implementation as long as you have a written a working version along with JUnit test.
This Java Generics interview question is based on correct understanding of raw type in Generics.
Main difference between raw type and parameterized type List< Object > is that, compiler will not check type-safety of raw type at compile time but it will do that for parameterized type and by using Object as Type it inform compiler that it can hold any Type of Object e.g. String or Integer.
Second difference between them is that you can pass any parameterized type to raw type List but you cannot pass List to any method which accept List< Object > it will result in compilation error.
This generics interview question may look related to previous interview questions but completely different.
List< ? > is List of unknown type while List< Object > is essentially List of any Type. You can assign List , List to List< ? > but you can not assign List to List< Object >.
List<?> listOfAnyType;
List<Object> listOfObject = new ArrayList<Object>();
List<String> listOfString = new ArrayList<String>();
List<Integer> listOfInteger = new ArrayList<Integer>();
listOfAnyType = listOfString; //legal
listOfAnyType = listOfInteger; //legal
listOfObjectType = (List<Object>) listOfString; // compiler error - in-convertible types
javac compiler for Java 5 generates unchecked warnings if you use combine raw types and generics types. e.g.
List rawList = new ArrayList()
Note: Hello.java uses unchecked or unsafe operations.;
which can be suppressed by using @SuppressWarnings("unchecked") annotation.
This Generics interview question is similar to difference between raw type and parameterized type.
Parameterized type are type-safe and type-safety will be guaranteed by compiler but List raw type is not type safe.
You can not store any other Object on List of String but you can not store any Object in raw List.
There is no casting required in case of Parameterized type with Generics but explicit casting will be needed for raw type.
List listOfRawTypes = new ArrayList();
listOfRawTypes.add("abc");
listOfRawTypes.add(123); //compiler will allow this - exception at runtime
String item = (String) listOfRawTypes.get(0); //explicit cast is required
item = (String) listOfRawTypes.get(1); //ClassCastException because Integer can not be cast in String
List listOfString = new ArrayList();
listOfString.add("abcd");
listOfString.add(1234); //compiler error, better than runtime Exception
item = listOfString.get(0); //no explicit casting is required - compiler auto cast