• 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

What's the reason ?

 
Ranch Hand
Posts: 111
Netbeans IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
public static <T extends Number> void hello(Collection<T> aa){ } is perfectly valid but


public static <T super Number> void hello(Collection<T> aa){ } is not valid why?


Regards,

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


public static <T super Number> void hello(Collection<T> aa){ } is not valid why?



Because if were allowed, it wont help you anymore!
Upper bound like <T extends Number> opens a lot thing to be done, lower bound
like class <T super Number> is not allowed for the following reason:

1- If you say <T extends Number>
Collection<Long> c1;
Collection<Integer> c2;
Collection<Float> c3;
Collection<Byte> c4;
...
...
all are permitted to be passed to hello method.

And think about the case when <T super Number> were allowed to us.

2- The upper bound gives access to all the non static methods of the class,
where as lower bound would give only limited methods accessibility. In our
case only to Number and Object (Number extends Object). So of very little use.


3-In method <T extends Number> hello(Collection<T extends Number> c) {...}
all occurrences of T would be replaced by the upper bound Number.
But think of the upper bound case if allowed,
It would become
... hello(Collection<Object> c) {...}, of very tiny use.



Regards,
cmbhatt
 
Abdul Mohsin
Ranch Hand
Posts: 111
Netbeans IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
you mean to say only because of "tiny use" sun make it compiler error
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


you mean to say only because of "tiny use" sun make it compiler error



What I mean "tiny use"?

I would call it of no use frankly!
See this parameterized class:



With the upper bound we are able to create Tiger object with all the parameterized type Red,Black and so on. And if the compiler allowed us the
lower type: Would it be of any use:



Is there any significant benefit of using the lower bound? Huh
NO.
In one line, if lower bound were allowed, it would give 1% of less benefit
against 99% or more over trouble of casting in each place.


Got it?


Regards,
cmbhatt
[ April 26, 2007: Message edited by: Chandra Bhatt ]
 
Abdul Mohsin
Ranch Hand
Posts: 111
Netbeans IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Excellent explaination,

Thanks,

Abdul Mohsin
 
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Seems like my Generics concept has gone for a toss

public static <T super Integer> void hello(java.util.Collection<T> aa){ } //Compiler error
public static void hello(java.util.Collection<? super Integer> aa){ }
//compiles fine

Aren't they essentially the same thing?
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey Dasa,

Don't loose hope yaar,
come back by going through following explanation:

First of all 2 facts for the exam, and whenever we see them anywhere lurking in the code, we can mark compiler error blindly

1- In class definition or parameterized declaration for a method, whenever
we see something the following



or


Both the codes give compiler error, because it is not permitted.



Swarna says,
public static <T super Integer> void hello(java.util.Collection<T> aa){ } //Compiler error
public static void hello(java.util.Collection<? super Integer> aa){ }
//compiles fine



About the first line I have talked in above posts.

The second one say, the method hello will accept a Collection parameterized
with Integer or superclass of Integer of-course Number and Object. Nothing
else. It was talk about what reference variable we can send to this. Now let us see in the case of lower bound what benefit we have against upper bound
Collection<? extends Integer>.

In the case of upper bound , you simply understand it as READ ONLY.
Nothing can be added to it. It is only for reading.

In the case of lower bound as Collection<? super Integer> c,
we are allowed to add Integer. Take care I am talking about the add() method, {not about what reference can be passed} that is Integer object can be added to the c.

Question? Why is it allowed in case of lower bound?
Answer:
1- Because it is safe to do, If you pass Collection<Integer>, adding Integer object is so far so goo.

2- If you pass Collection<Number>, adding Integer, no problem, Number is parent
class of Integer.

3- If you pass Collection<Object>, no issue, Object is super class of Integer.

Besides Integer, compiler wont allow to add anything.


Type erasure:
Colletion<? extends Number>
will become
Collection<Number>

Collection<? super Number> will become
Collection<Object> after type erasure by the compiler.





Regards,
cmbhatt
 
swarna dasa
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Bhatt!!!

But i am still not clear.

I am aware of the fact that with classes we can't use wild card(?) or T super Number but thought that we can use it in methods.
https://coderanch.com/t/262205/java-programmer-SCJP/certification/Why-invalid-syntax

I am aware of why we can use it in lower bounds, and agree with your explanation there. Also understand <? super XYZ> allows adding objects of type XYZ

What i don't understand is the difference between these 2 methods


In statement 2 isn't it that T is type ? super Integer, so why is it that compiler works fine with line 1 and not line 2.

What is the exact difference between line 1 and line 2?
[ April 26, 2007: Message edited by: swarna dasa ]
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well Swarna,

Let me come very specifically to your favorite two lines



Line 1: Provides adding facility against <? extends Integer> that is read only as you know it well. ? means unknown type, but what is known that, it must be Integer or super class of Integer.

Line 2: If it was allowed, more trouble less (say it NO) gain.
If it was allowed we would have (1-) restriction in creating object of that
class, (2-) Only allowed to access methods of the lower bound classes, Number or Object.
"super" bound would support you is the restriction that only
supertypes of Number can be used as type arguments. Is there any benefit of
going though such an trouble for that funny restriction.

And finally when the type erasure makes it
void hello( <Collection<Object> c) {}
Did we get anything? NOTHING!!!

I see with cristal clear eyes that <T extends Number> or such has a lot of
benefits.

Finally I would say, we should hate the line <T super Number> or so!!!



Regards,
cmbhatt
 
swarna dasa
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Really appreciate your effort.

But a couple of queries:-

Comparing line 1 and line 2.




Value-add of line 1 or line 2 (if it was allowed) would be ability to add an object of type Integer to the Collection.

Cited reason
(1-) restriction in creating object of that class
Wouldn't the same restriction apply to line 1?
(2-) Only allowed to access methods of the lower bound classes Object.
Wouldn't that be the case for line 1 as well?
And finally when the type erasure makes it
void hello( <Collection<Object> c) {}

And finally , what would be the type erasure for the line 1?
[ April 26, 2007: Message edited by: swarna dasa ]
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cross questioning!!! GOOD


Value-add of line 1 or line 2 (if it was allowed) would be ability to add an object of type Integer to the Collection.

Cited reason
(1-) restriction in creating object of that class
Wouldn't the same restriction apply to line 1?
(2-) Only allowed to access methods of the lower bound classes Object.
Wouldn't that be the case for line 1 as well?
And finally when the type erasure makes it
void hello( <Collection<Object> c) {}
And finally , what would be the type erasure for the line 1?



Remember:
In line 2
public static <T super Integer> void hello(java.util.Collection<T> aa){ } //line 2

Very first you declare the bound of T and then use it in the method. It is must if T is not already the parameterized type of the class. It is the case
when you are defining generic method in the non-generic class, so you
must declare the type before you use it. (As you know it is must in the case of static methods too because they dont share the class parameter type).

The same case is not true in the case of "?", because ? mark is known as unknown type and while making signature of the method you can simply dictate
that the parameter of this method is "? super something" or "? extends something";

To think, whether wrong thing was permitted would it behave like right thing looks funny to me!

The final gotcha was type erasure of the <T super Number> that becomes
<Object> in compilation process. So storing everything is object make us people of non generic type era, even after so must trouble.

You know these all generics, parameterized type stay here only, what is left ultimately is the pure bytecode where there is no sign of parameterized type or so. These all things are available to restrict we naughty programmers(sorry if it hurts anybody), who are in habit of adding wrong thing without any care.



Regards,
cmbhatt
 
swarna dasa
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am not too sure if i need to take this offline now, but if i have confused someone reading this thread, i don't want to leave them in this abyss (guess have exaggerated)


Very first you declare the bound of T and then use it in the method. It is must if T is not already the parameterized type of the class
Agreed

The same case is not true in the case of "?", because ? mark is known as unknown type and while making signature of the method you can simply dictate
Agreed

Not digressing from my questions.




(1-) restriction in creating object of that class

According to me, the same restriction is applied to line 1 and line 2.

(2-) Only allowed to access methods of the Object.
Yes, I can only get an object in both cases.

And finally when the type erasure makes it
void hello( <Collection<Object> c) {}

As we know this is going to be erased by the compiler the type erasure for line 1 also would be
void hello( <Collection<Object> c) {}

Let me know if any of my answers are wrong.

If not, then why is it that the compiler errors out on line 2.
I practically see no difference in both the lines.

Please pardon my limited knowledge on Generics.
 
Chandra Bhatt
Ranch Hand
Posts: 1710
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You are talking something like!
"If my aunt was Male, I would call her Uncle"




Take it lightly please!


Thanks,
cmbhatt
[ April 26, 2007: Message edited by: Chandra Bhatt ]
 
swarna dasa
Ranch Hand
Posts: 108
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Read a couple of FAQ, just wanted to update the links:-

A wildcard can have a lower or an upper bound, while there is no such thing as a lower bound for a type parameter.
http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#FAQ203

Why is there no lower bound for type parameters?
http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#Why%20is%20there%20no%20lower%20bound%20for%20type%20parameters?

Understand that it doesnt make sense for Classes but guess the same is simply propogated to methods as well.
 
Ranch Hand
Posts: 558
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Swarna,

Case 1>

public static void hello(java.util.Collection<? super Integer> aa){ } //line 1

This is ordinary method takes a Class Object which has been implemented as a generic class.

After Type Erasure becomes

public static void hello(java.util.Collection aa){ } //Nothing will remembered



CASE 2>

public static <T super Integer> void hello(java.util.Collection<T> aa){ } //line 2

This is ofcourse comes under "generic method declaration" but its wrong.

For generic methods T will be replaced with compatible Object depending on its filter<T super Integer> in "Type Erasure" process.

Since your filter is <T super Integer>

it has to replace Collection<T> with Collection<Object> ( i will tell
you why Object next)
But generic stuff can't remembered at Runtime.
Hence you will be stopped on this stamtement.

***
Generic methods will include direct type. like
public static <T super Integer> void hello(T aa) { } //line 2
This is fine. After type Erasure it will become

public static void hello(Object aa) { } //line 2
But there is no need to have a method like that with Object
Hence usage of T super XXX has been ruled out.
Why menas hello(Number) is valid call but it can't make use of its
methods in hello bec'ze we are passing it to Object.
------------------------------------------------------------------
Why Object has been replaced for T in this example ???


For <T super Integer> JVM has to select upper bound which will take
any super class Integer!.


Object is only choice which can accomodate any class which is
"super to" Integer or any other.

So <T super xxx> will always be replaced(T Arguemnts) with Object.
(So its useless to have function like this which will accept Object)
-------------------------------------------------------------
<T extends Car> is valid in generic methods. Why ?
Lets see what happens with <T extends Car>

public static <T extends Car> void hello(T aa) { } //line 2
//After Type Erasure becomes
public static void hello(Car aa) { } //line 2

This is so simple.
<T extends Car> means any class that extends Car is valid.
So as Car can hold any of its Childs like Benz,BMW,Lancer..

So the generic notation would be
before erasure <T extends xxx>
After erasure argument T replcaed with xxx.

----------------------------------------------------------------
***


[ April 27, 2007: Message edited by: Srinivasan thoyyeti ]
 
Abdul Mohsin
Ranch Hand
Posts: 111
Netbeans IDE Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks , really good explaination of type erasure.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic