• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Rob Spoor
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Tim Holloway
  • Piet Souris
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Frits Walraven
  • Himai Minh

OCP Java SE 11 Programmer II Study Guide (Sybex 816) Errata Chapter 3 LVTI and Generics interaction

 
Bartender
Posts: 1059
33
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Full understanding of Java Generics is one of the trickier parts of the topics covered on the OCJP, IMHO.

I am getting pretty good at it, most of the subtleties come about due to compatibility constraints for pre-generic Java code and implications of type erasure.

The coverage in Chapter 3 isn't bad, but the introduction of var and Local Variable Type Inference bring about some new subtleties and weirdnesses.

The coverage of this particular issue is found on page 156 of the two-book set, and is quoted here for all to be able to discuss:

Finally, let's look at the impact of var.  Do you think these two statements are equivalent?





They are not.  There are two key differences.  First x1 is of type List, while x2 is of type ArrayList.  Additionally, we can only assign x2 to a List<Object>.  These two variables do have one thing in common.  Both return type Object when calling the get() method



So originally I was taking issue with the sentence:

Additionally, we can only assign x2 to a List<Object>



English is a very ambiguous language.  I immediately confirmed my suspicion that we could assign x2 to an ArrayList<Object>, a Collection<Object> and an Object.



Then I realized that what the sentence must have meant was that only x2, but not x1, can be assigned to a List<Object>
Okay, yeah, that makes sense, tho I would have written it just like that...

But are those definitely the two obviously most important differences??

Here are some more that seemed exceptionally important to me to note:

These are all logical consequences of the declared type of x2 being implicitly ArrayList<Object>, which makes me think the best thing to say about it is that the declaration of x2 is identical in semantics to:
ArrayList<Object> x2 = new ArrayList<>();

But there are other important differences to keep in mind for both certification and general use of Java Generics, also following from the fact that x1 is of type List<?> and x2 is of type ArrayList<Object>.  What can we successfully add to each:

x1:  Nothing.  Zip, Nada.  We can't possibly add anything to that stupid List<?>, not because it is a List, but because it has an unbounded type parameter.  We can only REMOVE things from it, but never add or change any.

x1.add(new Object());
x1.add("Wowza!");
x1.add(3.1415986);
x1.add(System.out);

yields errors like:
The method add(capture#4-of ?) in the type List<capture#4-of ?> is not applicable for the arguments (Object)
The method add(capture#7-of ?) in the type List<capture#7-of ?> is not applicable for the arguments (PrintStream)
Yikes.  If I was comfortable with error messages like that, I could have stuck with C++.  But yeah, you can't add or modify any elements in any Collection with an unbounded type parameter.
I guess that "capture#4 of ?" is referring to the workings of the Generics wildcard feature in this class....regardless, you just can't add things to Collections containing unbounded type parameters.

Because the type of x2, on the other hand, is inferred to be ArrayList<Object>, well, I can't think of anything I CAN'T add to it:
// all tickety-boo!
x2.add(new Object());
x2.add("Wowza!");
x2.add(3.1415986);
x2.add(System.out);


I love strong static typing and hate sticking objects of unrelated classes into an ArrayList as much as any Scala programmer would, but it is all totally legal, my lawyer/compiler assures me.
That's a pretty big difference too.
Ditto on calling all the methods that might alter the List in question:

Similarly with attempts to modify any of the element values:
x1.set(0, "Woof");  // no go! The method set(int, capture#4-of ?) in the type List<capture#4-of ?> is not applicable for the arguments (int, String)
x2.set(0, "Woof");  // go go go!!


Interestingly, a List<?> isn't really immutable, there's a lot you CAN do with it apparently, tho the book tells us for the purposes of the 819 exam we can imagine it is immutable.

x1.remove("Dog Food");  // we can't add but removing is fine
x1.clear(); // heck, we could remove EVERYTHING if we want
Collections.shuffle(x1);  // just don't look under the shells as we move 'em!


So, action item?
How about just changing the sentence that threw me bouncing down this Rabbit Hole:

They are not.  There are two key differences.  First x1 is of type List, while x2 is of type ArrayList.  Additionally, we can only assign x2 to a List<Object>.  These two variables do have one thing in common.  Both return type Object when calling the get() method



To something like:

They are not.  There are numerous differences, all of which are direct consequences of the first one being declared with a List type with an unbounded type parameter and the second being precisely equivalent to:
ArrayList<Object> x2 = new ArrayList<>();

 
author & internet detective
Posts: 40726
827
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I made a note to look at this for the next book.

I loved the lawyer/compiler assures you it is legal comment
 
Jesse Silverman
Bartender
Posts: 1059
33
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What is funny, is while researching past posts to ensure I am not double-posting things here, I saw all the Usual Suspects taking bets YEARS AGO, on which Java Version that Raw Type usage would finally be turned into a compiler error and not just an unchecked or unsafe warning.  All were wrong.

It isn't happening in 17 either, is it?
 
Jeanne Boyarsky
author & internet detective
Posts: 40726
827
Eclipse IDE VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:It isn't happening in 17 either, is it?


No. I wouldn't expect it to ever. That's a big break on backward compatibility. Save this link in case I'm wrong to show it .
 
Anderson gave himself the promotion. So I gave myself this tiny ad:
the value of filler advertising in 2021
https://coderanch.com/t/730886/filler-advertising
reply
    Bookmark Topic Watch Topic
  • New Topic