Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

mock exam question doubt - generics arraylist

 
Mike Mitchel
Greenhorn
Posts: 12
Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is from whizlabs OCAJP 7 Mock



I was expecting class cast exception at run time. As String "0067" can't be added to a List<Integers>. But I am wrong, This compiles and prints 0067. Can somebody kindly explain?
 
K. Tsang
Bartender
Posts: 3585
16
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suspect it's because the addToList() method. The parameter isn't List<String> or List<Integer> or similar with a specific "type" but just List, meaning anything (not type safe).

Hope this helps.
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Mark,

A little bit of history will make you understand this question without any problem. Before Java 5 you wrote code like this:


So you could add really everything to a List and the developer had to be very careful when working with collections. Although the list is named myIntegers there is no way to prevent other things (like strings and dogs) to be added to that list. When you retrieved the items from the list, you always got Objects and you had to cast them to the appropriate type (if you want to invoke a specific method). And when you cast, you have to be very, very careful (or you got a ClassCastException slapping you in the face; auwch, that hurts! ). So if we want to print the previous list, you had to write(before Java 5) code like this:


Without the instanceof operator you would get a ClassCastException (a String is not an Integer). You can spot the cons with the naked eye:
  • You get some boilerplate code (casting, instanceof check) that you have to do with each collection in your code
  • There is no guarantee that if you have a list with integers it only contains integers
  • ...


  • That's why in Java 5 generics were introduced. It made the code more concise, easier to read and you have compile time protection. So in your list with integers you can only add integers. The above code in Java 5 or later versions (also using the enhanced for loop):


    So like I said before: more concise and easier to read. But one important not about generics: these generic types only exists at compile time! At runtime it's just a List (like in before java 5). The compiler adds the necessary casts for you (you can see that when you "decompile" a compiled class using Jad for example.

    Now Java is known for its backwards compatibility, so you can mix generic list with non-generic lists. You can pass a generic list without any problem to a method with a non-generic list. So the non-generic list from the addToList-method is exactly the same as the List from the above "before java 5" example, so you can add everything you fancy: strings, integers, cats, dogs, planes,... When you retrieve the elements, some caution is needed: in the mock question you simply print the element to the console. That's why the code compiles and runs without any problem. Every class inherits a toString-method from Object (and that's the method invoked when printing to the console).
    If you wanted to invoke a specific Integer method, you needed a cast on line 15: System.out.println(((Integer)lst.get(0)).intValue()); And that's when the ClassCastException will occur, because you don't have an Integer, but a String. If line 14 was replaced by lst.add("0067"); you would have a compiler error because you try to add a String to a generic list which can only (if all the code uses generics ) contain integers.

    Phew, what an explanation! Hope it helps!
    Kind regards,
    Roel
     
    K. Tsang
    Bartender
    Posts: 3585
    16
    Android Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Further to what my good buddy Roel said, you can print out the "type" too.



    To test for different types, try adding in 2 elements say an integer and a string. Then use a for loop to get the class:



     
    Roel De Nijs
    Sheriff
    Posts: 10662
    144
    AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    And you would think that's all about generics. Unfortunately, this isn't even half the story When you are preparing for the OCPJP7 certification you'll learn/see much more subtleties and little things you need to know about generics.
     
    Mike Mitchel
    Greenhorn
    Posts: 12
    Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Roel . Thats great explanation. Thanks tsang as well.
     
    Roel De Nijs
    Sheriff
    Posts: 10662
    144
    AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Nice to know: instead of making a "thank you" post, you could also +1 the post(s) which you liked. It's easier, faster and other ranchers will see immediately which are the "starred" posts.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic