Overloading return values

· Tiger

I will start this post talking about StringBuffer and StringBuilder. As some might know, Java 5.0 added the new StringBuilder class with the same interface as StringBuffer's. I can only rant about the name choice: If Sun really wanted the StringBuilder to only serve as an unsynchornized version of StringBuilder, maybe they should have used the same pattern they had with synchronized collections and maps, with a method like StringBuffer.unsynchronized(StringBuffer) or something similar, much like Collections.synchronizedList(List). These two classes don't even implement the same interface. It seems like the only reason for this weird naming is to make it easier to find for people who've seen the same class in dotNet. But maybe that's just my feeling. Okay, enough rant. While looking at the classes, I noticed they implement Appendable, which provides methods such as Appendable Appendable.append(char). However, StringBuffer provides a method StringBuffer StringBuffer.append(char), and has no other method returning Appendable. Now, maybe I'm just finding out something very old here, but I made a small test and wrote the following:

public interface a {
  a doSomething();
}

public class b implements a {
  b doSomething();
}

Not being able to become surprised by now, it compiled successfully. A short look using javap revealed:

l~/test $ javap code.a
Compiled from "a.java"
public interface code.a{
    public abstract code.a doSomething();
}

l~/test $ javap code.b
Compiled from "b.java"
public class code.b extends java.lang.Object implements code.a{
    public code.b();
    public code.b doSomething();
    public code.a doSomething();
}
Apparently, the bytecode contains an overload which differentiates by return value only! Obviously, doing such a thing manually would cause a compilation error. I wonder how far back this feature went? I think it's new.. But don't have the time to start searching for something written about it.

Comments (7)

Rob Sanheim
This is allowed in java 5 only due to carviant return types: http://java.sun.com/developer/JDCTechTips/2005/tt0104.html#2
Avah
This is a new feature, then.. Should look into the bytecode a bit further. :)
StringBuilder vs. String at Chaotic Java
[...] The sharp eyed might notice that in J2SE 5.0, a new class was introduced called StringBuilder, while up until then there was a class called StringBuffer. Well, StringBuffer is still there, and I’ve discussed their differences earlier as an aside of a different post. [...]
Bihnar
It can also happen due to two methods with different type parameters... Apparently it's legal to have two methods with the same name, same parameters, different return type and different type parameters. Why? Who knows... Seriously, if you know who knows, please say so. public class TwoMethodsDifferingOnlyInReturnTypeAndTypeParameters { public static int method() { return 0; } public static float method() { return 0; } }
Bihnar
AAAArgH stupid angle brackets. let's try that again. public class TwoMethodsDifferingOnlyInReturnTypeAndTypeParameters { public static <T extends String> int method() { return 0; } public static <T extends Thread> float method() { return 0; } }
Avah
Bihnar - It happens because of the different return types. It wouldn't be allowed if the return types were the same. Remember that generics in Java are erased during compilation. They mean nothing in the bytecode level. It's like "compiler-hints".
Avah
But I understand what you mean - With generic methods, its allowed to do that even in a class and not just by overloading an inherted method. (Took me time to understand what you mean entirely :))