Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

Post Reply
admin
Site Admin
Posts: 9353
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by admin »

Note: This article assumes that you are clear about the is-a concept in OO. i.e. A subclass "is-a" superclass. For example, an Integer is-a Number (because Integer extends Number). This implies that every Integer is-a Number but every Number is not necessarily an Integer. A Number could be a Double or Long (or any other subclass of Number) also. As another example, Dog is-a Animal, but every Animal is not Dog.

Understanding Generics is quite simple, if you understand the following three basic principles:


1. The main purpose of having generics is to prevent corrupting (or polluting) a collection of objects. In other words, to avoid putting random things into any collection. After all, you want things neatly organized. You don't want to put apples in a sack of potatoes. Similarly, when you take things out of a sack of apples, you expect apples to come out and not potatoes or anything else. At the same time, if you have a "basket of fruit", you should be able to put any fruit such as an orange, an apple, or a Mcintosh apple into that basket. But, and here is the twist, when you pick a fruit from that basket, do you always expect to get an apple? No, right? You could get any fruit because it is a basket of fruits, and not a basket of apples!

That's the fundamental thing and the hardest to absorb (I bet you are rolling your eyes ).

Now, the simpler stuff:

2. ? extends Apple: This means "of a class that extends Apple". Therefore, List<? extends Apple> means a sack of some variety of Apple. Mcintosh? Probably. But you don't know. In other words, "? extends Apple" does not mean "any class that extends Apple". It means a specific but unknown class that extends Apple.

Q. When you are given a sack of "? extends Apple", can you put a Mcintosh in it? If you have any doubt, read point 1 again. (Hint: Do you want to mess up your sack of Fuji apples by putting a Mcintosh apple it it?)
Answer: No, you can't put a Mcintosh apple in a sack of "? extends Apple" because what if the sack is of Fuji apples? Putting a Mcintosh apple into a sack of Fuji apples would corrupt/pollute the sack of Fuji apples and we don't want that to happen.

Q. When you take out stuff from a sack of "? extends Apple", what do you get? An Apple for sure. Right? Could you get a Potato? A a Mcintosh or a Fuji apple?
Answer:You will never get a Potato. You get some kind of Apple. You don't know the exact kind. It could be a Mcintosh or a Fuji apple but you have no idea which one. Therefore, you can assign it directly to a variable of type Apple but you cannot assign it directly to a variable of type FujiApple. You will need to cast it to assign it to a variable of type FujiApple.

The important thing is, why would anyone want to declare a variable of type List<? extends Apple> if they can't put any Apple into it? The answer is that they want to share their List of apples with others but they don't want others to pollute that list by adding random types of apples into that list. This property makes it very useful as return type of a method. For example,

Code: Select all

List<? extends Apple> getApples(){
  return new ArrayList<FujiApple(); //the developer of the method is free to return an ArrayList of Mcintosh apples as well.
}
3. ? super Apple: This means "of a class that is a super class of Apple". Therefore, List<? super Apple> means a sack of something of which an Apple is a kind. Let's call it "it". So, what do you call a sack of something of which an Apple is a kind? A sack of fruits! Are you sure? Can you not call it a sack of food items? or A sack of Mcintoshes? (Hint: Every apple is a kind of fruit. Every apple is a kind of food item. But is every apple a kind of Mcintosh?) So, which of these statements should work?

Code: Select all

List<? super Apple> listOfSuperApple = getListofSuperAppleSomehow(); 
listOfsuperApple.add(anApple); 
listOfsuperApple.add(someFruit); 
listOfsuperApple.add(aMac); 
Read 1 again, if in doubt.

Answer:

Code: Select all

listOfsuperApple.add(anApple); //Correct, because any apple can be put in a sack that is meant to store apples, fruits, or fooditems, or Objects. 
listOfsuperApple.add(someFruit); //Wrong, because what if the sack is of apples and someFruit is pointing to a Pineapple?
listOfsuperApple.add(aMac); //Correct, because any apple can be put in a sack that is meant to store apples, fruits, fooditems, or Objects. 
Q. When you take out stuff from a sack of "? super Apple", what do you get? Apple? Probably. A fruit? probably. Some food item? probably. Are you sure? No. So, what are you sure of? Well, it is something, but you don't know what. Actually, you are sure of nothing. So, which of these statements should work?

Code: Select all

Apple a = listOfsuperApple.get(0); 
Fruit a = listOfsuperApple.get(0); 
FoodItem a = listOfsuperApple.get(0); 
Object a = listOfsuperApple.get(0); 
Read 1 again, if in doubt.
Answer:

Code: Select all

Apple a = listOfsuperApple.get(0); //Wrong, because you don't know the type of objects stored in the list. What if the list is of type FoodItems, and contains a Pineapple as well?
Fruit a = listOfsuperApple.get(0); //Wrong, what if the list is of type FoodItems, and contains a Pizza?
FoodItem a = listOfsuperApple.get(0); //Wrong, what if the list is of type Object and contains a String?
Object a = listOfsuperApple.get(0); //Correct, because no matter what is stored in the list, it is definitely an Object!  
So, is List<? super Apple> useful at all? Yes, you can use it when you want to want a container that can accept any and all kinds of Apples in a List but not let anyone know the exact type of items the List is meant to contain. That's what makes List<? super Apple> different from List<Apple>. You can add any Apple to a List<Apple> and take out Apples from it. But you can only add apples to List<? super Apple>.

Quiz: What would List<?> mean? What can you put in it and what can you take out from it?
Answer <?> means something specific but not known. It doesn't mean "anything". It is like you get a sack from a fruit vendor and he tells you that it contains only a specific fruit, say Banana, but doesn't tell you exactly which fruit. It doesn't mean it contains various kinds of fruits. It contains only one kind of fruit but you don't know which one. If he sent you a sack of bananas, you can't put any fruit it in because you don't know the exact type of fruit it contains. Similarly, when you take something out from the sack of <?>, you can't assign it to any specific class other than Object because you don't know what exactly does the sack contain.


That's it! If you understand point 1 above, you will never miss any question on generics. Ever!
If you like our products and services, please help us by posting your review here.

Kostik
Posts: 2
Joined: Sat Oct 27, 2012 3:35 am
Contact:

Re: Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by Kostik »

The best explanation of wildcards which I have ever seen!
Thanks

admin
Site Admin
Posts: 9353
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Post by admin »

When to use ? super Apple and when to use ? extends Apple

Very easy - if you want to eat Apples from a bag, you should look for a bag of Apples. i.e use ? extends Apple. For example, List<? extends Apple>. This will allow you to take out Apples from the bag because you know that whatever you take out of this bag will definitely be an Apple. Remember, anything that extends Apple IS-A Apple.

If you want to dump Apples into a bag, you can dump them into a bag of Apples or into a bag of Fruits or into a bag of FoodItems. But you can't dump them into a bag of FujiApples, right? (Because not every Apple is a FujiApple, don't forget that!) In other words, use ? super Apple. For example, List<? super Apple>. This will let you add any Apple to the list.

Quiz
1. What can you dump into List<? extends Apple>?
2. What can you eat from List<? super Apple>? (Hint, can you eat Object?)
If you like our products and services, please help us by posting your review here.

johnnie
Posts: 1
Joined: Wed Mar 25, 2020 3:34 pm
Contact:

Re: Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by johnnie »

IMHO this is the worst explanation ever, if people are coming here to understand that means they don`t understand how it works at the moment. It is very confusing giving them an bastract example of Apple and Mcintosh and then asking questions which are crucial to be answered, but are left unanswered.

admin
Site Admin
Posts: 9353
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by admin »

Hi Johnnie, Thanks for your feedback. The answers have been added. Hope it is helpful to you now :)
If you like our products and services, please help us by posting your review here.

ketank
Posts: 10
Joined: Thu Apr 15, 2021 9:02 am
Contact:

Re: Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by ketank »

'Enlightening' is the word ! It took me an hour to read it and re-read it until I got it right.
I didn't understand generics in its true sense before. Awesome explanation. Thanks a ton.

happypie
Posts: 1
Joined: Fri Apr 23, 2021 7:36 am
Contact:

Re: Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by happypie »

I am a bit confused with this example:

3. ? super Apple: This means "of a class that is a super class of Apple". Therefore, List<? super Apple> means a sack of something of which an Apple is a kind. Let's call it "it". So, what do you call a sack of something of which an Apple is a kind? A sack of fruits! Are you sure? Can you not call it a sack of food items? or A sack of Mcintoshes? (Hint: Every apple is a kind of fruit. Every apple is a kind of food item. But is every apple a kind of Mcintosh?) So, which of these statements should work?

Code: Select all

List<? super Apple> listOfSuperApple = getListofSuperAppleSomehow(); 
listOfsuperApple.add(anApple); //Correct, because any apple can be put in a sack that is meant to store apples, fruits, or fooditems, or Objects. 
listOfsuperApple.add(someFruit); //Wrong, because what if the sack is of apples and someFruit is pointing to a Pineapple?
listOfsuperApple.add(aMac); //Correct, because any apple can be put in a sack that is meant to store apples, fruits, fooditems, or Objects.

List<? super Apple> means a bag of furit, a bag of food items or a bag of objects (anything which can be super class of Apple).

Why this wouldn't work?
listOfsuperApple.add(someFruit);

a pinnaple is also an object so this bag should accept that.

admin
Site Admin
Posts: 9353
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: Concepts and Quiz on Generics ( com.enthuware.ets.scjp.v6.1.824 )

Post by admin »

Because listOfSuperApple could be a List of Apples also, and someFruit could refer to an Orange. And if listOfSuperApple is actually a List of Apples, then putting an Orange in a List of Apples would ruin it.

Code: Select all

class Fruit{ }
class Apple extends Fruit{ }
class Orange extends Fruit{  }
class FujiApple extends Apple{ }

public class TestClass
{
    public static List<? super Apple> getListofSuperApple(){
        ArrayList<? super Apple> af = new ArrayList<Apple>();
        af.add(new FujiApple());
        return af; //here, af is actually pointing to a List of Apples
    }

   public static void main(String[] args)
   {
       List<? super Apple> listOfSuperApple = getListofSuperApple(); //here listOfSuperApple is actually pointing to a List of Apples!

       Fruit someFruit = new Orange();

       listOfSuperApple.add(someFruit); //This will not compile. But if it did, then you are basically putting an Orange into a List of Apples.
   }

}
The tricky part here is that class Apple is "a class of which an Apple is a kind" and therefore class Apple satisfies "? super Apple". That is why List<? super Apple> af = new ArrayList<Apple>(); works.

The compiler doesn't know what listOfSuperApple will actually point to at run time. But it knows that it could point to a List of Apples. And so, it doesn't like the idea of putting an Orange in that list.
If you like our products and services, please help us by posting your review here.

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 6 guests