Win a copy of Java Persistence with Spring Data and Hibernate this week in the Spring forum!
  • 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
  • Tim Cooke
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • Junilu Lacar
  • Rob Spoor
  • Jeanne Boyarsky
Saloon Keepers:
  • Stephan van Hulst
  • Carey Brown
  • Tim Holloway
  • Piet Souris
Bartenders:

'Generic' and int questions

 
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I have couple of basic questions.

1) When I instantiate a List as follows:
List <? extends Integer> intList = new ArrayList<Integer>;
List <?> intList = new ArrayList<Integer>;


What is the meaning of using the wildcard notation? I read that it means nothing can be added. Then what is the point of creating a list if nothing can be added?
Also what is the difference between <? extends Integer> and <?> in the reference?

2) Please look at the following code (taken from a practice test from the ranch):



The explanation says:
lthree and lfour are two seperate objects. if the lines 1 and 2 were lthree = 2 and lfour = 2 the result would have been true. This is when the objects are created in the pool. When the references i and eye in the pool are compared 2==2 results in true and 2000==2000 is false since it exceeds 127

First I dont get why 2000==2000 is false and the relationship with the 127.
Secondly, the '==' operator compares the addresses of the objects. So prints 'false' in the println. But when compared inside the 'method' why does it return true?
Does the method autounbox the Integer obects?
If so can't I use any Interger class methods on the objects passed in to the 'method'?

Thank you.
 
author
Posts: 23936
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

What is the meaning of using the wildcard notation? I read that it means nothing can be added. Then what is the point of creating a list if nothing can be added?



Well, you don't create a list with wildcards, that doesn't make any sense. In fact, the way that you are using wildcards is not very common (except with examples) either.

The common usage of wildcards is with parameters of methods. And the reason for it is so that you can have a method that would work on a broad range of types. If you want to write a method that would traverse the list to calculate a value, and can work in a broad range allowed by wildcards, then why not?

Also what is the difference between <? extends Integer> and <?> in the reference?



The first states that it is an unknowm type (that is known to extend Integer (or is Integer). The second is just an unknown type.

Henry
 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maduranga Liyanage wrote:
2) Please look at the following code (taken from a practice test from the ranch):



The explanation says:
lthree and lfour are two seperate objects. if the lines 1 and 2 were lthree = 2 and lfour = 2 the result would have been true. This is when the objects are created in the pool. When the references i and eye in the pool are compared 2==2 results in true and 2000==2000 is false since it exceeds 127

First I dont get why 2000==2000 is false and the relationship with the 127.


This is from The Java Language Specification (5.1.7. Boxing Conversion):


If the value p being boxed is true, false, a byte, a char in the range \u0000 to
\u007f, or an int or short number between -128 and 127, then let r1 and r2 be
the results of any two boxing conversions of p. It is always the case that r1 ==
r2.


Maduranga Liyanage wrote:
Secondly, the '==' operator compares the addresses of the objects. So prints 'false' in the println. But when compared inside the 'method' why does it return true?
Does the method autounbox the Integer obects?
If so can't I use any Interger class methods on the objects passed in to the 'method'?


When you call the method with i3 and i4 as arguments, since these are int variables and the method's parameters are Integer variables, autoboxing takes place. And since then the parameters are Integers with value 2 (therefore between -128 and 127), they actually refer to the same object.

The method doesn't autounbox the Integer objects, because there are no operations inside the method that require unboxing. You are comparing two Integer references using the equality operator. When neither the left nor right hand side operand is a numeric primitive, autounboxing won't take place.
 
Maduranga Liyanage
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much for the replies.
I still got some confusion over this.

1) So what the objective means is, if I box an int in the range -128~127 twice, the resulting objects will be the same?
for example;
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
Integer i3 = new Integer(125);


Then, i1==i2, but i2 != i3, correct?
So i1 and i2 actually point to the same object? Is this because Integer objects are immutable, like String objects?

2) I still dont understand the concept of declaring a List in this manner. Maybe it doesnt make sense, but I found it in a practice exam, and would like to know its meaning.

a. List <? extends Integer> intList = new ArrayList<Integer>;
b. List <?> intList = new ArrayList<Integer>;


The explanation said that nothing can be added to the List created this way. Then whay does Java allow to instantiate a List in this manner, if nothing is allowed to be added?


Thank you very much.

 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maduranga Liyanage wrote:Thank you very much for the replies.
I still got some confusion over this.

1) So what the objective means is, if I box an int in the range -128~127 twice, the resulting objects will be the same?
for example;
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
Integer i3 = new Integer(125);


Then, i1==i2, but i2 != i3, correct?
So i1 and i2 actually point to the same object? Is this because Integer objects are immutable, like String objects?


Actually, you only benefit from the pool if you use autoboxing. When you use the new keyword there will be always a new object created, so the example above is wrong.

You need to do:
Integer i1 = 127;
Integer i2 = 127; // i1 == i2 is true

You could also use the valueOf() method of the Integer class, which also uses a cache (but I'm not sure if it is subject to the range restrictions that autoboxing has for using the cache.) And notice that the range restrictions, even for autoboxing, are the minimum range where this will work, I think that specific implementations of the JVM are at liberty to cache wider ranges.

For example,

Integer i1 = Integer.valueOf(127);
Integer i2 = Integer.valueOf(127); // i1 == i2 will return true

Maduranga Liyanage wrote:
2) I still dont understand the concept of declaring a List in this manner. Maybe it doesnt make sense, but I found it in a practice exam, and would like to know its meaning.

a. List <? extends Integer> intList = new ArrayList<Integer>;
b. List <?> intList = new ArrayList<Integer>;


The explanation said that nothing can be added to the List created this way. Then whay does Java allow to instantiate a List in this manner, if nothing is allowed to be added?


Thank you very much.


You can still access elements in the list, can't you? But like Henry said, the wildcard construct is mostly used for method parameters, to allow more flexibility. If you want flexibility and to be able to add elements, you need to set a lower bound (instead of a lower bound) for the generic type, using <? super Integer> for example.

If I'm wrong Henry will correct me.
 
Maduranga Liyanage
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you very much Ruben.
I understood the Integer problem.

But still not 100% on the Generics. It is after all a very annoying topic.
I don't understand how I can 'access the elements' if I cannot put anything into the list in the first place?
And initializing with <?> means I can add anything or nothing? If I can add anything, then what is the meaning of the <Integer> in the right hand side?

Thank you very much.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maduranga Liyanage wrote:Thank you very much Ruben.
I understood the Integer problem.

But still not 100% on the Generics. It is after all a very annoying topic.
I don't understand how I can 'access the elements' if I cannot put anything into the list in the first place?
And initializing with <?> means I can add anything or nothing? If I can add anything, then what is the meaning of the <Integer> in the right hand side?

Thank you very much.


Yes, generics is an issue that can be quite counterintuitive.

You need to realize that generics are only good for the compiler, and the purpose of generics is to enforce compile-time type safety, which basically means that it is a way for the compiler to tell you when you are doing something you shouldn't be doing (like adding an element of a type where you shouldn't be adding it.)

When you have a List<?> reference you don't know anything about the actual type of the list. That's why you can't add anything to it, because the compiler doesn't know anything about the type of the list, so it will stop you from adding anything (since no matter what type of element you add, it might be a bad decision based on the actual type of the list.)

With List<?>, the only thing you know is that the elements are of type Object (as everything is ultimately an instance of Object.) So you could go through the List<?> reference, and invoke the toString() method in each element, because toString() is defined in Object.

Now, if you do List<? extends Number> you know that the actual type of the list is either Number, Integer, Float, Double, etc. But you still can't add anything to it, because no matter what you add, you might violate the type safety of the list. However, because you know that all elements of the list are instances of Number, you can call any Number methods that you want in each element. Obviously, you could still call any Object methods on the elements as well, since Object is a supertype of Number.

But if you do List<? super Integer> you know that the actual type of the list is either Integer, Number, of Object. Because you have bounded the possible types downwards, you can add Integer instances (or instances of any subtype of Integer) because in that case type safety won't be violated.

Does this clarify things a little? Let me know what else I can help you with.
 
Maduranga Liyanage
Ranch Hand
Posts: 124
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you soo much Ruben. That was great. Actually it also cleared some other confusions I had with Generics.
Thank you again.
Cheers.
 
Ruben Soto
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Maduranga Liyanage wrote:Thank you soo much Ruben. That was great. Actually it also cleared some other confusions I had with Generics.
Thank you again.
Cheers.


Great, Maduranga!
 
You guys wanna see my fabulous new place? Or do you wanna look at this tiny ad?
The Low Tech Laboratory Movie Kickstarter is LIVE NOW!
https://www.kickstarter.com/projects/paulwheaton/low-tech
reply
    Bookmark Topic Watch Topic
  • New Topic