• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Understanding Generics

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

I have been studying generics at webpage and have a couple of doubts on the difference between
wildcards and bounded parameters.

From the content on the site i seem to have come to the conclusion that both serve the same purpose.

A bounded type

public void <T> doSomething(T extends Number myNumber){
}

implies the same as

public void doSomething(<? extends Number> myNumber){
} which uses wildcards.


Am i right to assume that or are there any further nuances that am too shortsighted to see.

 
author
Posts: 23951
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

Can you show us compilable code? The first example isn't valid code, so we can't tell what you are trying to say.

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


Above is the code. I fooled around and reviewed the documentation at sun's website. I have revised my query to understand what is the contextual usage of the wildcard '?'.

Also, am i right to state that the only way to create generic 'type' is using parameter variable like T,S,U in the type declaration.

I was so far of the opinion that constructs like <? extends Number> could be stated in the following type declaration.

"private class MyInnerClass<? extends Number>" or "private class MyInnerClass<?>"

But i get a complie time error stating invalid token '?'

 
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can only use the wildcard for variable declarations and return types.

The difference between the wildcard and other type parameters is that the wildcard says you don't care what the type is:
The first one means: The code calling getNumbers() will know exactly what type the List will be of. For instance:This will return a List of Doubles.
The code calling the second example doesn't care about the exact type of the list. It knows the type will extend Number, and that's all it needs.
 
Ranch Hand
Posts: 433
Netbeans IDE
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The best resource regarding generics can be found here: Angelika Langers Java Generics FAQs
If you start with generics, you should read it.
 
Shridhar Raghavan
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
@ Stephen

Thanks for the post. But i haven't quite got what you tried to put across. Both code seem to declare that they return a list of numbers.
What is the difference?

Also

The first one means: The code calling getNumbers() will know exactly what type the List will be of

and

The code calling the second example doesn't care about the exact type of the list. "It knows the type will extend Number"

Both statements say the same thing.
 
Henry Wong
author
Posts: 23951
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

Shridhar Raghavan wrote:
Thanks for the post. But i haven't quite got what you tried to put across. Both code seem to declare that they return a list of numbers.
What is the difference?



There is not enough code to make a clean distinction here. The first case, declares a generic method that will return a list of something that extends number. The second case, is a method that returns a list of something that extends number. The distinction is that the compiler can figure out what the T is for the first case, and doesn't have a T, and may not figure out the type for the second case.

This distinction is not very clear here. So, yes, in this example, "both code seem to declare [a method] that return a list of numbers".


Shridhar Raghavan wrote:
The first one means: The code calling getNumbers() will know exactly what type the List will be of

and

The code calling the second example doesn't care about the exact type of the list. "It knows the type will extend Number"

Both statements say the same thing.



Actually, no. The first case actually knows what type T is at compile time. It knows more that "the type will extend Number", the compiler actually can figure out the type.

Henry
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, there is a slight difference. The code calling the first example will know *exactly* what type the List is of. For instance, it will know that it is *exactly* a List<Double>, or a List<Integer> etc.

Code calling the second example doesn't know this. It only knows that whatever the List is a List of, it is a Number.

With the second example, you will only be able to retrieve Numbers from the list. With the first example, you will be able to retrieve Integers, or Doubles or any specific type of Number. I will illustrate this. First example:
You wouldn't be able to determine whether the values in the list were non-numbers if we used the wildcard extending Number, since Number doesn't provide the isNaN() method.

If you can do less using the wildcard, then why use the wildcard at all? For the same reason methods return interfaces, and not specific types: If we return a more general type, we can change the implementation more easily later on. List<? extends Number> is more general than List<Double> or List<Integer>.

[edit]
My post is in response to Shridhar, of course
 
Shridhar Raghavan
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator



Hi, Thanks for the posts.

Tried experimenting and have a couple of issues. Got these four errors which i have been trying to reason out. Have listed out my points.
 
Henry Wong
author
Posts: 23951
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

Shridhar Raghavan wrote:



1. The reason you can't return List<Number> is because you need to return a List<T>, and you can't guarantee that T is always Number.

2. The reason you can't return List<Double> is because you need to return a List<T>, and you can't guarantee that T is always Double. Now, in line 19 of your example, T is indeed Double, but there is no guarantee that you will always use it that way.

Henry
 
Henry Wong
author
Posts: 23951
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

Shridhar Raghavan wrote:



This requires some explanation. A List<? extends Number> is *not* interchangeable with a List<Number>. A List<Number> is indeed a list of numbers. A List<? extends Number> is a list of something very specific. It could be a List<Double>. It could be a List<Integer>. It is just that the compiler doesn't know what it is. If the compiler allows the assignment, and let's say for example, it is originally a List<Double>, then you now have a mechanism to add Integer objects into a List<Double>, which breaks typing.

Henry

 
Henry Wong
author
Posts: 23951
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

Shridhar Raghavan wrote:



Same explanation as the previous post -- a List<Double> is not interchangeable with a List<? extends Number>. And be careful with casting. Casting may remove the error message, but you may be breaking type checking with it. If done right, there should not be a need to cast.

Henry
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Edit]
Again, Henry was quicker

3. You're tring to assign a List<? extends Number> to a List<Double> variable. You can't do this, because a List<? extends Number> could be a List<Integer> or a List<Float>.

4. Same issue as 3.

5. You're telling getNumbersWithBoundedParams() that you're expecting a List<Number>, so this is what you're getting. This is called type inference. You're expecting a List<Number> so the compiler tells that the method should return a list of this type.
 
Shridhar Raghavan
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have got the point 3 & 4 cleared.

Summing it up here, it would help to view what the wild card method would do.

1 - It would at runtime create a list<Double> or a list<Integer>.

2 - Now if we assigned a reference of List<Number> to the above objects, the purpose of the list would break, as with the reference you could do an "add(Integer())" later and what if the returned object was a list<Double>. Havoc

i guess the same theory applies to assigning a reference of List<Double> to the returned object.

@Henry Wong,

Regarding 1 & 2,

Could you sum up the behavior of a bounded parameter method invocation.

If it helps, here's what i gathered from your posts,

When you declare the return type as generic, like a <T extends Number>, your returned object needs to have that generic parameter type "T" in the return statement..

like a return type of List<T> --> return new ArrayList<T>(); or return new LinkedList<T>();

a return type of Map<K,V> --> return new HashMap<K,V>();


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


Hi,

What's wrong with the following code? My intent is to create a class that is an array list and defines it's own type parameters as well.

Do i have to use MyDataStruct<T,E>
 
Stephan van Hulst
Saloon Keeper
Posts: 15510
363
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If the parameter is different from the one in ArrayList, then yes, you have to declare two parameters.

What is it exactly you're trying to do?
 
Shridhar Raghavan
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was trying to figure out the intended behavior of generic structures. Now if i just used MyDataStructure<T> extends ArrayList<E>, i get a compilation error stating the type parameter is undefined. What is the reason behind this? Actually sounds ridiculous to me as well, but why can't i change the parameter type name. How would hypothethically, having the ability to create "MyDataStructure<T> extends ArrayList<E>" break any code?
 
Shridhar Raghavan
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also could someone just help out with my last post on generics dated "Tuesday, February 22, 2011 00:19:39". The part directed towards Henry Wong.
 
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Shridhar Raghavan wrote:I was trying to figure out the intended behavior of generic structures. Now if i just used MyDataStructure<T> extends ArrayList<E>, i get a compilation error stating the type parameter is undefined. What is the reason behind this? Actually sounds ridiculous to me as well, but why can't i change the parameter type name. How would hypothethically, having the ability to create "MyDataStructure<T> extends ArrayList<E>" break any code?


The type you are creating is MyDataStructure<T>. That only has one generic type, and it's T. So when you then have extends ArrayList<E> - what is E? If you want E to be a parameterised type of MyDataStructure, you have to declare it.

So either of the following compile (and which you'd use depends on what you're trying to achieve):


Obviously it's a different situation, but there's a parallel with method arguments, and that might be more intuitive. Consider the following:
Would you expect that to work? Or would you expect to have to do one of these?

 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Shridhar Raghavan wrote:Also could someone just help out with my last post on generics dated "Tuesday, February 22, 2011 00:19:39". The part directed towards Henry Wong.


If I understand the question here - this is what the issue is.

Remember that List<String> is not a List<Object>, and a List<Integer> is not a List<Number>. The generic type has to be exactly the same for them to match like this. So if you're declaring a method to return a List<Number>, then that's what you've got to return. Having a return value based on a generic type doesn't change anything. If your method says it returns a List<T>, that's what it's got to return. Whether you've put constraints on the type makes no difference to what you return. [It does make a difference to what you can put in and get out of the list, but that's a different issue].

Does that make sense?

If you're using the ? wildcard this gets a bit more complicated, but don't worry about that until you fully understand how it works without wildcards.
 
Shridhar Raghavan
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey,

Does that make sense?



Ya i do get the reasoning behind List<Integer> not being a List<Number>. It's actually with the wild card bit i keep getting stuck.

If you're using the ? wildcard this gets a bit more complicated, but don't worry about that until you fully understand how it works without wildcards.



So you can continue to explain the wild card bit or guide me to a place to look into .
 
Matthew Brown
Bartender
Posts: 4568
9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry - the thread goes in a few different directions so it wasn't clear which bits you're uncertain about.

One good resource was posted above, and there's also the official Java Generic Tutorial. For the big picture they're a good choice, but if you've got specific questions I can try and help.

With generics, I find the key question is to keep asking "what does the compiler know?". Most of the behaviour can be determined from that. For instance, you've got a reference type List<? extends Number> - what does the compiler know about the object it references? It knows it's a List of a specific type, and it knows that type is Number or a subclass. But it doesn't know which subclass. So what can we safely add to it? And what do we know about things stored in it?
 
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Matthew Brown wrote: . . .
One good resource was posted above, and there's also the official Java Generic Tutorial. . . .

And Joachim Rohde posted a link to Angelika Langer's website, which is another good resource.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic