|
From: Timbo on 8 Sep 2005 10:10 Hi everyone, A question about type inferencing in Sun's compiler: I have the following factory method for creating an empty list: public static <E> List<E> list() { return new java.util.ArrayList<E>(); } Now, consider the following method that takes a list of String: private void useStringList(List<String> stringList) { ... } I can invoke "useStringList" on an empty list as follows: List<String> strList = Factory.list(); useStringList(strList); The compiler will infer from "List<String> strList" that the return type of "Factory.list()" is "List<String>" in this instance. However, take the following snippet: useStringList(Factory.list()); The compiler complains that "useStringList" cannot be applied to "List<Object>". Why is it that it can infer the type in the former example, but not the latter? I am aware that I can write: useStringList(Factory.<String>list()); but this is a bit comvoluted when compared to just "Factory.list()", and there is certainly enough information to infer the type. Thanks, Tim
From: Oliver Wong on 8 Sep 2005 14:58 "Timbo" <timbo(a)noreply.invalid> wrote in message news:dfpr24$4if$1(a)kinder.server.csc.liv.ac.uk... > Hi everyone, > > A question about type inferencing in Sun's compiler: I have the following > factory method for creating an empty list: > > public static <E> List<E> list() > { > return new java.util.ArrayList<E>(); > } > > Now, consider the following method that takes a list of String: > > private void useStringList(List<String> stringList) > { ... } > > I can invoke "useStringList" on an empty list as follows: > > List<String> strList = Factory.list(); > useStringList(strList); > > The compiler will infer from "List<String> strList" that the return type > of "Factory.list()" is "List<String>" in this instance. However, take the > following snippet: > > useStringList(Factory.list()); > > The compiler complains that "useStringList" cannot be applied to > "List<Object>". Why is it that it can infer the type in the former > example, but not the latter? I am aware that I can write: > > useStringList(Factory.<String>list()); > > but this is a bit comvoluted when compared to just "Factory.list()", and > there is certainly enough information to infer the type. Because of method overloading, you must know the types of your parameters before you can choose which method to call. In the line "useStringList(Factory.list());" the compiler doesn't know yet which useStringList is going to be called until it knows the type of Factory.list(). So it first evaluates the type of Factory.list(). Since there is no context information saying otherwise, it determines Factor.list() to return an object of type List<Object>. Now it tries to find a method matching the signature useStringList(List<Object>) and finds none, hence the error. - Oliver
From: Roedy Green on 8 Sep 2005 18:19 On Thu, 08 Sep 2005 18:58:14 GMT, "Oliver Wong" <owong(a)castortech.com> wrote or quoted : >Because of method overloading, you must know the types of your >parameters before you can choose which method to call. In the line >"useStringList(Factory.list());" the compiler doesn't know yet which >useStringList is going to be called until it knows the type of >Factory.list(). So it first evaluates the type of Factory.list(). Since >there is no context information saying otherwise, it determines >Factor.list() to return an object of type List<Object>. Now it tries to find >a method matching the signature useStringList(List<Object>) and finds none, >hence the error. does not the parameter overload matching proceed totally ignoring genericity? -- Canadian Mind Products, Roedy Green. http://mindprod.com Again taking new Java programming contracts.
From: John C. Bollinger on 8 Sep 2005 21:19 Roedy Green wrote: > does not the parameter overload matching proceed totally ignoring > genericity? Pretty much yes. As I understand it, method signatures are not differentiated one from another by genericity, which means among other things that you cannot have overloaded versions of a method that differ only in their type parameters. This is an implication of type erasure. The compiler checks type parameter compatibility after determining the appropriate method to invoke (without consideration of type parameters). Oliver's [elided] explanation of why type is not inferred for method arguments may nevertheless be about right, but it seems to me that it calls out an issue with the compiler architecture rather than anything inherent in the type system. I wonder whether it's really just a shortcut to limit the intelligence that the compiler needs to exercise. -- John Bollinger jobollin(a)indiana.edu
From: Chris Uppal on 9 Sep 2005 04:17 John C. Bollinger wrote: > Oliver's [elided] explanation of why type is not inferred for method > arguments may nevertheless be about right, but it seems to me that it > calls out an issue with the compiler architecture rather than anything > inherent in the type system. I wonder whether it's really just a > shortcut to limit the intelligence that the compiler needs to exercise. Another place where it seems that the compiler /should/ be able to infer types, but does not is in conditional code. E.g. (from memory) List<String> stringList = null; if (...) stringList = Factory.list(); else stringList = ASimilarFactory.list(); is OK, but: List<String> stringList = (...) ? Factory.list() : ASimilarFactory.list(); is not. Personally, I'm going off this type inference fast[*] (and I wasn't too keen on it in the first place), but if we are going to have it, then at least it should be done properly... -- chris ([*] It seems obfuscatory, and is also IMO contrary to the spririt of a language in which byte b = ...; byte lowNybble = b & 0x0F; is not allowed. )
|
Next
|
Last
Pages: 1 2 3 Prev: Good examples of programming course lecture notes Next: Clear Screen??? |