This discussion is archived
1 2 3 Previous Next 32 Replies Latest reply: Jun 12, 2010 8:09 PM by 843793 RSS

What does the return type " <T> T" mean?

843793 Newbie
Currently Being Moderated
Hi,

I've recently stumbled over a method in an interface I need to implement which looks like:
 <T> T methodName();
I've never seen such a strange return type, it would be great if somebody could take the patience and just explain short whats all this is about.
So ok the <T> is some generic universal type I guess, but whats about that single T after it?

Sorry for the dumb question.

Thank you in advance, Clemens
  • 1. Re: What does the return type " <T> T" mean?
    608410 Newbie
    Currently Being Moderated
    Clemens,

    <T> is a type parameter whose scope is the method. T is the return type of the method.

    That particular interface method is probably an abomination.

    The method signature uses generic methods (it has type parameters local to the method). This one says the return type is whatever you specify it to be when you call it, or whatever you want it to be if you don't specify.

    for example
    Integer i = that.methodName()
    means the method will return an Integer. or
    Object x = that.<Double>methodName()
    means the method will return a Double.

    Of course this is all ridiculous because there is no way for the method to know what the required type is, so it cannot do what is asked.

    This voodoo magic can be used to avoid the caller having to cast the return result from a method that can return multiple types, where the caller knows what to expect in some way. However if the caller gets it wrong, you won't know till runtime when you will get a ClassCastException. This particular use of generic methods tends to suggest that the author of the method was highly incompetent with using generics.


    How this is supposed to work is that the generic methods type parameter can be used to infer relationships between the types of various arguments and the return type. For example [Collections.singleton()|http://java.sun.com/javase/6/docs/api/java/util/Collections.html#singleton(T)]

    If you see a generic method where the type parameter is only used for the return type, it is almost always an abomination. A case where it is valid is for example [Collections.emtyList()|http://java.sun.com/javase/6/docs/api/java/util/Collections.html#emptyList()] becuase an empty list is actually a list of whatever you want.

    If you told us what the method was supposed to do, we could determine whether it is in fact an abuse of the language or is valid.

    It may be that you can implement this method, but it is more likely that you are expected to perform some magic.

    Bruce
  • 2. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    brucechapman wrote:
    This voodoo magic can be used to avoid the caller having to cast the return result from a method that can return multiple types, where the caller knows what to expect in some way.
    Mhh, the caller can certainly avoid explicitly casting the returned value; no cast at all won't pass byte code validation (assuming the required type is not a supertype of the upper bound).
    However if the caller gets it wrong, you won't know till runtime when you will get a ClassCastException.
    As opposed to getting it wrong with an explicit cast?
    This particular use of generic methods tends to suggest that the author of the method was highly incompetent with using generics.
    I fail to reach this conclusion.
    SomeType var = someMethod();
    // vs
    SomeType var = (SomeType)someMethod();
    Both lines of code indicate that if someMethod returns normally the returned object better be of SomeType. I'm sure an argument can be made for making the cast explicit/visible, but jumping to incompetence is a stretch.

    With kind regards
    Ben
  • 3. Re: What does the return type " <T> T" mean?
    608410 Newbie
    Currently Being Moderated
    The only way to implement this abstract method
     <T> T methodName();
    is for all execution paths to do one of the following:

    1. return null

    2. cause the compiler to issue an unchecked warning (optionally suppressing this warning) [(see JLS 5.5)|http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5]

    3. throw an exception

    2 is not type safe. 1 and 3 imply a void method

    Hence my assertion that the author is not competent with generics.

    The correct thing to do is to pass an argument whose type also depends on T so that the code can use that information in some way to either return null or throw an exception when the return value is not of the expected type.

    An example of methods which would benefit from this treatment are in this class

    It this case the caller might know what particular subtype the element ought to be, but there are no guarantees they are correct. If you want that sort of 'wishful runtime typing' then don't use a statically typed language.
  • 4. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    Hi,

    Thanks for your answers - I simply cast the resturn value to <T> now and it seems to work.
    We got that interface at university ;)

    Thanks again, Clemens
  • 5. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    brucechapman wrote:
    The only way to implement this abstract method
     <T> T methodName();
    is for all execution paths to do one of the following:

    1. return null

    2. cause the compiler to issue an unchecked warning (optionally suppressing this warning) [(see JLS 5.5)|http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5]

    3. throw an exception

    2 is not type safe. 1 and 3 imply a void method

    Hence my assertion that the author is not competent with generics.
    Well, that's a nice leap of logic. There may very well be a protocol as to which types are returned when, a protocol which is separate from anything the Java compiler can reason about. An example of this would be object deserialization.
    The correct thing to do is to pass an argument whose type also depends on T so that the code can use that information in some way to either return null or throw an exception when the return value is not of the expected type.
    I thought the whole point of this was type safety? You won't get that due to type erasure, even with TypeLiterals a là guice -- an instance of List<Integer> can't be shown not to be a List<String>. If you'd be happy with just testing against the relevant Class (uh oh, unchecked warning..) then deserialization gets by without passing it in just fine.
    It this case the caller might know what particular subtype the element ought to be, but there are no guarantees they are correct.
    There are never any guarantees. javac is not Coq; when a Java compiler accepts code without warning that does not mean it's correct.
    If you want that sort of 'wishful runtime typing' then don't use a statically typed language.
    So are you calling anyone who has ever used reflection or (de)serialization incompetent as well? Isn't any downcast "wishful" runtime typing?

    With kind regards
    Ben
  • 6. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    BenSchulz wrote:
    brucechapman wrote:
    2. cause the compiler to issue an unchecked warning (optionally suppressing this warning) [(see JLS 5.5)|http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5]
    Well, that's a nice leap of logic. There may very well be a protocol as to which types are returned when, a protocol which is separate from anything the Java compiler can reason about. An example of this would be object deserialization.
    Which still would require #2, an unchecked cast.
    I thought the whole point of this was type safety? You won't get that due to type erasure, even with TypeLiterals a là guice -- an instance of List<Integer> can't be shown not to be a List<String>. If you'd be happy with just testing against the relevant Class (uh oh, unchecked warning..) then deserialization gets by without passing it in just fine.
    Programmers understand that ClassCastExceptions can occur when they make an explicit cast. It's usually safe to assume that when you're not doing a cast, you won't get a ClassCastException.

    However, with code like this:
    public <T> T readObject() {
       return (T) readNextObjectFromStream();
    }
    
    //...
    String name = readObject();
    String address = readObject();
    Date dateOfBirth = readObject();
    You are essentially deliberately hiding type-unsafety from the caller. That's bad library design. Even if you don't suppress the unchecked warning, the compile warning is at the library method, not the caller method. But the ClassCastException would be generated at the CALLER, and that's not cool.
  • 7. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    endasil wrote:
    BenSchulz wrote:
    brucechapman wrote:
    2. cause the compiler to issue an unchecked warning (optionally suppressing this warning) [(see JLS 5.5)|http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.5]
    Well, that's a nice leap of logic. There may very well be a protocol as to which types are returned when, a protocol which is separate from anything the Java compiler can reason about. An example of this would be object deserialization.
    Which still would require #2, an unchecked cast.
    Absolutely, so what?
    I thought the whole point of this was type safety? You won't get that due to type erasure, even with TypeLiterals a là guice -- an instance of List<Integer> can't be shown not to be a List<String>. If you'd be happy with just testing against the relevant Class (uh oh, unchecked warning..) then deserialization gets by without passing it in just fine.
    Programmers understand that ClassCastExceptions can occur when they make an explicit cast. It's usually safe to assume that when you're not doing a cast, you won't get a ClassCastException.
    You are casting though, ergo you should not feel safe. When retrieving an element from a list you might get a CCE too, when retrieving an int from a list you might also get a NPE. None of this is explicit, it could happen anyways. People tend to be surprised for a couple of seconds and then they go "ahh, auto unboxing"; why should this be any different? Are the language designers incompetent too?
    [...]
    You are essentially deliberately hiding type-unsafety from the caller. That's bad library design. Even if you don't suppress the unchecked warning, the compile warning is at the library method, not the caller method. But the ClassCastException would be generated at the CALLER, and that's not cool.
    Why is that not cool? Is anyone with marginal understanding of the Java language going to expect the compiler to verify something that is not even part of the code? I'm reading from a stream of basically random objects, of course there'll be a cast there.

    All I'm doing is removing the redundancy, I see clear parallels to the Java 7 diamond operator.

    With kind regards
    Ben
  • 8. Re: What does the return type " <T> T" mean?
    608410 Newbie
    Currently Being Moderated
    Ben,

    The casting argument is irrelevant to this discussion. If the caller is expected to downcast to a specific type, then the method would have a return type of Object (or some other common super type of all possible return types). What this method has is a return type of whatever the caller wants. The only way an implementation can comply with that contract is the 3 means already discussed.

    In other words this signature could be tested by the following
    import java.util.Random;
    
    public class Test {
    
        public static class Impl {
            <T> T someMethod() {
                return null; // TODO replace with non trivial implementation
            }
        }
    
        public static void main(String[] args) {
            Random r = new Random(System.currentTimeMillis());
            Impl sut = new Impl();
            boolean alwaysNull = true;
            for(int i=0; i < 10000; i++) {
                if(r.nextBoolean()) {
                    String s = sut.someMethod();
                    if(s != null)alwaysNull = false;
                } else {
                    Test t = sut.someMethod();
                    if(t != null)alwaysNull = false;
                }
            }
            assert ! alwaysNull;
        }
    }
    can you come up with an implementation of Impl.someMethod() that always terminates normally with assertions enabled and doesn't compile with unchecked warnings?

    And if not how can you say that the author's use of generics is not highly incompetent?

    But its not necessarily fair for me to pose a programming challenge on you (especially one that I feel is impossible). So alternatively I'll let you propose some semantics for the OP's method signature, and possibly even a few sibling method signatures if necessary to elaborate, and I claim that I can write a better signature for someMethod, better in terms of capturing the semantics and competence with generics.

    If this is a university course assignment, then we need to keep our minds open to both possibilities that this is a trick question (in which returning null should achieve an A pass :) ), and that butchery of generics is acceptable. It would be interesting to know whether there are additional semantics (eg javadocs or other narrative) for this method that Clemens has not told us about.

    Bruce
  • 9. Re: What does the return type " <T> T" mean?
    EJP Guru
    Currently Being Moderated
    I always found it surprising that the case where a return type <T> can't be inferred from the arguments is even legal. Any background on that?
  • 10. Re: What does the return type " <T> T" mean?
    608410 Newbie
    Currently Being Moderated
    although the type inference algorithm in the JLS is littered with Discussions, it is surprising silent (section 15.12.2.8) about using return type, and certainly nothing about this case.
  • 11. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    Hello Bruce,
    brucechapman wrote:
    The casting argument is irrelevant to this discussion.
    By decree?
    If the caller is expected to downcast to a specific type, then the method would have a return type of Object (or some other common super type of all possible return types).
    Or, taking up the ObjectInputStream.readObject() example from above, the user is no longer forced to make that cast explicit. It is added for him by the compiler.
    What this method has is a return type of whatever the caller wants. The only way an implementation can comply with that contract is the 3 means already discussed.
    And there is nothing wrong with that; ObjectInputStream.readObject() already has the return type of whatever the caller wants: (a) I doubt anyone is serializing instances of java.lang.Object so (b) any call to readObject() is invariably followed by a downcast. (c) Most of the time (in my experience) the result is cast immediately and assigned to a variable or returned:
    SomeType var = (SomeType) ois.readObject(); // becomes: SomeType var = ois.readObject();
    // or
    return (SomeType) ois.readObject(); // becomes: return ois.readObject();
    Would you disagree with either (a), (b) or (c); if so why? And if not then what is wrong with having the compiler add these thoroughly redundant casts?
    can you come up with an implementation of Impl.someMethod() that always terminates normally with assertions enabled and doesn't compile with unchecked warnings?
    (I assume you meant to ask for an implementation that does not return null and eventually terminates.)
    Obviously not as that would leave the type system unsound. As far as I know Java 5 has never been proven to be sound, but it's a safe assumption.
    And if not how can you say that the author's use of generics is not highly incompetent?
    Because having no unchecked casts is -- by itself -- not a goal worth pursuing.
    But its not necessarily fair for me to pose a programming challenge on you (especially one that I feel is impossible). So alternatively I'll let you propose some semantics for the OP's method signature, and possibly even a few sibling method signatures if necessary to elaborate, and I claim that I can write a better signature for someMethod, better in terms of capturing the semantics and competence with generics.
    ObjectInputStream.readObject() -- have at it!

    Frankly, I suspect that your entire argument hinges on the premise that the library consumers are incompetent and unable to tell that a cast will (perhaps) be inserted for them.

    With kind regards
    Ben
  • 12. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    BenSchulz wrote:
    If the caller is expected to downcast to a specific type, then the method would have a return type of Object (or some other common super type of all possible return types).
    Or, taking up the ObjectInputStream.readObject() example from above, the user is no longer forced to make that cast explicit. It is added for him by the compiler.
    You say that as if it's a good thing. That's where we disagree. Generics are meant to give you the basic assurance that "if I don't cast, my code is type-safe (e.g. safe from ClassCastExceptions)". But the compiler taking away the need for the explicit cast makes it seem like the code is type-safe (since there's no explicit cast) while not improving the type-safety one bit. That is not a good thing. It completely subverts the benefits of generics and makes your code unsafe. It's just not a smart way to design a library.
    Frankly, I suspect that your entire argument hinges on the premise that the library consumers are incompetent and unable to tell that a cast will (perhaps) be inserted for them.
    That's not incompetence! It's really non-transparent! Why the heck would you want to do this when returning Object would be completely self-documenting that a cast is happening (because it's explicitly required!) Your argument hasn't actually stated a benefit of such a library design.

    Edit: If I don't cast, and there are no type safety warnings or errors, my code is type-safe.

    Edited by: endasil on 31-May-2010 10:30 AM
  • 13. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    BenSchulz wrote:
    what is wrong with having the compiler add these thoroughly redundant casts?
    [This says it well|http://java.sun.com/j2se/1.5.0/docs/guide/language/generics.html]:
    The net effect of using generics, especially in large programs, is improved readability and robustness.

    To paraphrase Generics Specification Lead Gilad Bracha, when we declare c to be of type Collection<String>, this tells us something about the variable c that holds true wherever and whenever it is used, and the compiler guarantees it (assuming the program compiles without warnings). A cast, on the other hand, tells us something the programmer thinks is true at a single point in the code, and the VM checks whether the programmer is right only at run time.
    Your readObject():
    -Reduces readability by making it appear that a compile-time check has occurred (through Generics) whereas it's a run-time check which is usually seen through a cast.
    -Fakes type-safety by moving the safety warning to the library, where the user of the library will never see it, and thus
    -Tricks the user of the library into thinking their code is type safe when it isn't (since there's no cast).

    In short, it subverts all of those identified benefits of Generics, and is therefore (in my eyes) a completely incompetent use of Generics.

    Any questions?

    Edited by: endasil on 31-May-2010 10:40 AM
  • 14. Re: What does the return type " <T> T" mean?
    843793 Newbie
    Currently Being Moderated
    By the way, I'm not saying there aren't any competent uses of type inference from the return-type alone. But I have only come across one, and yours isn't it at all.

    The only competent one I've come across is Collections.emptySet. In that case there is no issue of type safety and so the unchecked cast is completely acceptable.

    Edit: And Bruce already identified that.

    Edited by: endasil on 31-May-2010 10:47 AM
1 2 3 Previous Next