• 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
  • Tim Cooke
  • Devaka Cooray
  • Ron McLeod
  • Jeanne Boyarsky
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Carey Brown
  • Tim Holloway
Bartenders:
  • Martijn Verburg
  • Frits Walraven
  • Himai Minh

Generic method question

 
Ranch Hand
Posts: 1032
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This code is based (I believe) on one of Devaka's questions, which has been heavily modified.


The code compiles and runs successfully, and outputs (output is []).

I don't understand why it works though. At // 1, the generic parameter T should be getting resolved to String, since output is a List<String>. However, input (which is a List<Integer>) is not compatible with List<? super String>. This is not covered by K&B, and I doubt something like this would be in the exam, but I am interested in knowing how this is working.

Thanks,

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

I dont think that <code> output = BackLister.backwards(input);</code>
.should get compiled.

As you have already added that the generic parameter T would get resolved to String, since output is a List<String>. So, input List<Integer>) is not compatible with List<? super String>. This will work if you have output as List<Integer> output;

Which compiler are you using?
 
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
Hi Reji,

I'm using javac 1.6.0_07. Does this not compile for you?
 
reji singh
Ranch Hand
Posts: 52
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Ruben

Sadly this does get compiled on command line. I just went by logic. Just tried on 1.6.0_11 and 1.5.0_07 but it get complied and gives output [].

However, in eclipse it gives compilation which is right behaviour as per logic.
 
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
Thanks for checking Reji. I am sure there is some obscure generics rule which explains this behavior, and I'm also sure someone will probably point it out.
 
Ranch Hand
Posts: 66
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ruben,
You’ve just blown my mind with this one! If you had asked for something like this:



Then I would have a good answer for it, but not when you include that lower bound in the formal parameter of the backwards method. I started to thinking that maybe compiler inserts a method like the case for bridge methods, so I wrote a reflection code to prove it and I saw that was not the case too.
So, I don’t know. For sure it’s beyond the scope of SCJP (or at least it’s beyond the scope unless you don’t want to pass the exam with a 100% score), but like I said, it’s just blown my mind!
 
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
Morteza,

Thank you very much for looking into this. If anyone would come up with a solution for this problem, I'm sure it would have been you. Like you said, I'm sure it's nothing to worry about for the exam. But thanks for checking into it. Generics is a subject which I have the feeling becomes much tougher the more deeply you look into it, whereas those more advanced aspects of it are probably used in 0.00001% of the code.
 
Sheriff
Posts: 9697
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ruben, I cannot tell you the exact reason for the code working, but one thing's for sure, T doesn't resolve to String. This is because this modified code shows compilation error at (2)

 
Ranch Hand
Posts: 814
Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ruben your question on gemeric method is very good. I have seen it on yesterday night and try to find that why your code get compiled by compiler? what is the exact reason behind it?

Hello Ankit if T doesn't resolves to String then for which type T will resolve?

I have interest to know the reason why Ruben's code get compiled?

 
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

Ankit Garg wrote:Ruben, I cannot tell you the exact reason for the code working, but one thing's for sure, T doesn't resolve to String. This is because this modified code shows compilation error at (2)


I'm sorry Ankit, I don't follow your reasoning. In this case input is a List<Integer> reference, and that is why // (2) is failing. Still, I think that if you can assign the return of the method at // (1) to output (which is a List<String>), T must be resolving to String. The funny thing is that I couldn't make any actual parameter work (by doing output = BackLister.<String>backwards(input); and so on.)
 
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

Ninad Kulkarni wrote:Ruben your question on gemeric method is very good. I have seen it on yesterday night and try to find that why your code get compiled by compiler? what is the exact reason behind it?

Hello Ankit if T doesn't resolves to String then for which type T will resolve?

I have interest to know the reason why Ruben's code get compiled?


Ninad,

If Ankit and Morteza can't figure this one out I'm afraid we are out of luck.
 
Ranch Hand
Posts: 33
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ankit Garg wrote:Ruben, I cannot tell you the exact reason for the code working, but one thing's for sure, T doesn't resolve to String. This is because this modified code shows compilation error at (2)





Hi,

Actually T from Ruben's code and here at #1 resolves to the String.
But in #2 case it gives compilation error because the method backwards1 is not applicable to List<Integer> argument.
This method needs List<? super String> parameters.
If we pass super of String then T would get resolved to the particular passed parameters.
 
Ankit Garg
Sheriff
Posts: 9697
43
Android Google Web Toolkit Hibernate IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No one got my point actually. What I was trying to say is that if T resolves to String, then <? super T> is equivalent to <? super String>. And if you pass an Integer to <? super T> then it accepts it (although T is resolved to String). But it disallows to pass Integer to <? super String>.

Basically what I was trying to prove is that <? super T> with T resolving to String accepts Integer but not <? super String>. I know that T will resolve to String that is why you are able to assign the returning value to List<String>. Maybe this is a bug in the compiler and it should disallow it. I modified the method a bit and then the compiler disallows to send List<Integer> for <? super T>



Now the call at 1 generates a compilation error. With the addition of the second parameter, the compiler now knows that List<Integer> is not allowed for <? super T>. Maybe now T properly resolves to String...
 
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
I see now what you were trying to say, Ankit. This behavior is strange, maybe as you say this is due to a bug in the compiler.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic