• 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Devaka Cooray
  • Knute Snortum
  • Paul Clapham
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Ron McLeod
  • Piet Souris
  • Frits Walraven
Bartenders:
  • Ganesh Patekar
  • Tim Holloway
  • salvin francis

Type inferrence generic method.  RSS feed

 
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I ran across a piece of code that looked somthing like this on another site and it seriously blew my mind . How does the compiler infer the parameterized type of List<T> when the type is still unknown at the point of method invocation. Looks like Java voodoo to me.


[ March 15, 2006: Message edited by: Garrett Rowe ]
 
Ranch Hand
Posts: 336
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Never seen this before. Some what reminds me of Templates in C++.
 
Ranch Hand
Posts: 456
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
like you wrote, it's a generic method.

check this out:

sun generic tutorial, chapter 5

in my understanding, the first <T> in



declares T as a type (any type) that is used in List<T>.

jan
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In each case in the sample methods in that tutorial, the type <T> was inferred at the time of method invocation. Here <T> is unknown until the left-hand side of the assignment operator is evaluated, after the method call returns. Just looked kinda strange to me. I had never seen it done that way before.
 
author and iconoclast
Posts: 24203
43
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Garrett Rowe:
Here <T> is unknown until the left-hand side of the assignment operator is evaluated, after the method call returns.



Yeah, that's what I thought you meant. It is strange looking! Even stranger (until you think about it) is the fact that a bare call like

FinalTest.newList()

compiles too!

But the thing is that generics work by "erasure" which means that in reality, an ArrayList<String> is identical to an ArrayList<Object>. There are annotations in the class files that help the compiler reconcile types, but ultimately, at runtime, the types are gone. So if you write a method that returns a parameterized value with a free type parameter like this, then the compiler can simply treat it as a value of the "correct" type.
 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The type of T is inferred by the return type. If it cannot be inferred (you can come up with examples if you like), you will receive a compile-time warning. As far as I'm aware, this is common knowledge and not "strange" - is it not covered in the generics documentation?
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24203
43
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Tony Morris:
If it cannot be inferred (you can come up with examples if you like), you will receive a compile-time warning.



Actually, not so much. A bare call to the generic method in which the return value is discarded will compile without warnings; obviously no type parameter was supplied here. It doesn't matter in Java, but it sure as heck would matter in C++, where the code couldn't be compiled at all.

As far as I'm aware, this is common knowledge and not "strange" - is it not covered in the generics documentation?



It is. It's just strange looking to someone new to generics but with some C++ templates experience.
 
Garrett Rowe
Ranch Hand
Posts: 1296
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

If it cannot be inferred (you can come up with examples if you like), you will receive a compile-time warning.



This compiles without warning:


This however recieves a warning:
I can infer from this I guess that the unsafe operation is adding an element to the raw List.

[ March 15, 2006: Message edited by: Garrett Rowe ]
[ March 15, 2006: Message edited by: Garrett Rowe ]
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The warning you receive here is unrelated to type inference based on return type. I will come up with an example when I get a chance to demonstrate what I mean - I didn't mean simply invoking the method without a return type.

Or someone might like to come up with an example themselves
I recall many times when writing ContractualJ that I had to make sure an explicit invocation permitted a valid type inference.
 
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Originally posted by Garrett Rowe:
I can infer from this I guess that the unsafe operation is adding an element to the raw List.



Adding an element to any Collection where the parameterized type hasn't been declared will generate a warning. Why? Because a "List<String>" is a "List" and can be assigned to a variable of type List using widening reference conversion, which generates no warning. If the compiler allowed you to invoke generic methods on a raw List then you could add any Object to a List<String> without a warning.



I believe invoking any method that takes a parameterized type for a parameter will generate a warning if it's invoked on a raw type.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!