Return type determines override/overload...?
This might seem like a beginner's question and it probably is, but I want the Expert's answer ;)
Consider the following Java-5 code:
class Generic<T>{
}
class CompilesFine{
publicint id(Generic<Integer> request){
return 0;
}
publicbyte id(Generic<Double> request){
return 0;
}
}
class DoesNotCompile{
publicint id(Generic<Integer> request){
return 0;
}
publicint id(Generic<Double> request){
return 0;
}
}
In this code class CompilesFine compiles just fine, but class DoesNotCompile doesn't. You get an error saying there are duplicate methods. First off, I was hoping that since the type of a generic parameter is known at compile time, these methods in class DoesNotCompile would be overloaded. I know that the generics is only a compile time construction, but I thought that this would work anyway. Since the choice of which method a call is referring to is determined at compile time by the compile time argument, I do not understand why this wouldn't be possible.
This is not my big problem though. What I do not understand is why the same thing works just fine in class CompilesFine when the only thing I have changed is the return type. In all functional and imperative programming languages I have ever been in contact with, the signature of a function or method is always determined by its name and its parameter types. And I would wanna believe that it is the signature that determines if two methods clashes or not and the case of inheritance, if they are overridden or overloaded. But here, it seems a difference in the return type changes this behaviour.
I would be grateful for an explaination!
/Viktor
Message was edited by:
hedefalk
[2695 byte] By [
hedefalka] at [2007-11-27 10:14:11]

I'm surprised that CompilesFine is allowed.
> I'm surprised that CompilesFine is allowed.
Me too.
dwga at 2007-7-28 15:31:41 >

It doesn't with me. I get
Error(7,13): duplicate definition of method id(ovv.test.generics.Generic<java.lang.Integer>) in class ovv.test.generics.CompilesFine
OleVVa at 2007-7-28 15:31:41 >

This prints
1
2
public class CompilesFine {
public int id(Generic<Integer> request) {
return 1;
}
public byte id(Generic<Double> request) {
return 2;
}
public static void main(String[] args) {
CompilesFine cf = new CompilesFine();
System.out.println(cf.id(new Generic<Integer>()));
System.out.println(cf.id(new Generic<Double>()));
}
}
class Generic<T> {
}
This gives the error:
sandbox\CompilesFine.java:4: name clash: id(sandbox.Generic<java.lang.Integer>) and id(sandbox.Generic<java.lang.Double>) have the same erasure
public int id(Generic<Integer> request) {
sandbox\CompilesFine.java:8: name clash: id(sandbox.Generic<java.lang.Double>) and id(sandbox.Generic<java.lang.Integer>) have the same erasure
public int id(Generic<Double> request) {
2 errors
public class CompilesFine {
public int id(Generic<Integer> request) {
return 1;
}
public int id(Generic<Double> request) {
return 2;
}
public static void main(String[] args) {
CompilesFine cf = new CompilesFine();
System.out.println(cf.id(new Generic<Integer>()));
System.out.println(cf.id(new Generic<Double>()));
}
}
class Generic<T> {
}
I would have thought the different generic type would have differentiated them to the compiler too. Curious.
Yeah, it's the inconsistency that troubles me. The code:
class Generic<T> {
}
class CompilesFine {
public static int id(Generic<Integer> request) {
return 0;
}
public static byte id(Generic<Double> request) {
return 1;
}
}
public class A {
public static final void main(String[] args) {
System.out.println(CompilesFine.id(new Generic<Integer>()));
System.out.println(CompilesFine.id(new Generic<Double>()));
}
}
renders the output:
0
1
which would be expected if you could overload methods by using different type parameters on the generic type. Which you obviously can... But only if you also change the return type. This is for me very confusing and I will probably have nightmares about it ;)
/Viktor
OleW, which compiler do you use?
Simple. Generic types don't exist at runtime.
class X<T> {
}
public class Test {
public static void main(String[] args) {
X<String> h = new X();
X<Integer> k = new X();
System.out.println(k instanceof X); // true
System.out.println(h instanceof X); // true
//Therefore...
System.out.println(k.getClass() == h.getClass()); // true!
}
}
So all the compiler knows is...
public void(X<Integer> h)
public void (X<Double> k)
is basically read as
[code]
public void(X h)
public void(X k)
and If I could give my methods names, I'd be set for life! :-/
>So all the compiler knows is...
>
>public void(X<Integer> h)
>public void (X<Double> k)
>
>is basically read as
>public void(X h)
>public void(X k)
That doesn't explain why one works but the other doesn't. That reasoning is more consistent with rejecting both classes.
> >So all the compiler knows is...
> >
> >public void(X<Integer> h)
> >public void (X<Double> k)
> >
> >is basically read as
> >public void(X h)
> >public void(X k)
>
> That doesn't explain why one works but the other
> doesn't. That reasoning is more consistent with
> rejecting both classes.
I guess since the return type doesn't count in the signature, the compiler catches if the parameter types will be the same at runtime? Where's uj when you need her? :)
http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.2
> OleW, which compiler do you use?
1.5.
1.5.0_06 to be precise.
Are we beginning to suspect a possible error in the 1.6 compiler? I know we should hesitate before we think that.
OleVVa at 2007-7-28 15:31:41 >

Strangely enough, this the way the language spec seems to be.
See the evaluation here:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6182950
> Strangely enough, this the way the language spec
> seems to be.
>
> See the evaluation here:
> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=618
> 2950
Okej, so basically, what he's writing is that the type parameter is part och the signature so the methods have different signatures in both cases. On the other hand, the type parameter is not part of the erasure, but the return type is.
But when I read the definition of erasure in 4.6 it sais:
"The erasure of a method signatures is a signature consisting of the same
name as s, and the erasures of all formal parameter types given in s."
There is nothing about return types here...?
> > OleW, which compiler do you use?
>
> 1.5.
> 1.5.0_06 to be precise.
>
> Are we beginning to suspect a possible error in the
> 1.6 compiler? I know we should hesitate before we
> think that.
OleW, can you check again that you get a compile error on the CompilesFine class? According to the bug report from 2004 this SHOULD compile.
/Viktor
Okej, sorry. I missed the point:
"*IF* 8.4.8.3 said "the signature of m1 or some other method...has the same erasure as the signature of m2 or some other method...", then the return types wouldn't matter, by the definition of erasure on signatures in 4.5. But 8.4.8.3 actually says "m1 or some other method...has the same erasure as m2 or some other method...", so the return types do matter."
But the definition of erasure of a method is nowhere to be found. At least I can't find it. I interpret this that the erasure of a method includes the return type and that Sun's trying to sweep this under the carpet. Or even worse, they're building formal definitions on notion that hasn't been formally defined.
I'm getting more and more confused.
I did my test yesterday from with JDeveloper (my IDE) and got the error I told you.
Today I tried compiling from the command line (DOS prompt):
P:\PrivatWorkspace\Test\src\ovv\test\generics>javac -version CompilesFine.java
javac 1.5.0_11
P:\PrivatWorkspace\Test\src\ovv\test\generics>
It compiles fine! So either there is a difference between 1.5.0_06 and 1.5.0_11, or the error I got yesterday is from JDeveloper only, not from the Sun compiler.
OleVVa at 2007-7-28 15:31:46 >

I had been starting to think that maybe they had relaxed the conditions a bit between 1.5 and 1.6, but I changed my mind on that. I now told JDeveloper to use Java 1.5.0_11, and it still reports the error, so it's JDeveloper refusing to compile CompilesFine, it's not Sun's Java compiler.
"Sweep under the carpet"? I tend to buy the argument, there is no error in the compiler. In my experience, when I think there is one, in at least 9 out of 10 cases, there isn't.
Message was edited by:
OleVV
OleVVa at 2007-7-28 15:31:47 >

> "Sweep under the carpet"? I tend to buy the argument,
> there is no error in the compiler. In my experience,
> when I think there is one, in at least 9 out of 10
> cases, there isn't.
I can buy the argument since it correctly points to the difference in the language specification. I can't however buy the language specification just yet because I can't find the definition of erasure of a method, only the definition of erasure of a signature of a method. The argument points out the difference between erasure of signature of a method and erasure of a method itself. It even states that the return type is part of the erasure of a method. But I can't find this definition anywhere in the language specification. I'm not saying it isn't defined but I haven't found it and I am still looking. If it isn't defined, then the language specification is building formal definitions on an undefined notion, which is the eigth sin.
The worst part is that there is a good motive to deliberataly use an undefined notion in this definition since this hides the ugly fact that the return type is important to check for clashes.
Viktor: Sluta skriv i forum p jobbtid :)
/an
anamea at 2007-7-28 15:31:47 >

> Viktor: Sluta skriv i forum p jobbtid :)
>
> /an
sch, det hr r arbetsrelaterat juh! Dessutom kan jag inte sova p ntterna pga detta. Och det r viktigt att jag sover p ntterna s jag kan jobba bra p dagarna ;) Vem r du frresten?
> > Viktor: Sluta skriv i forum p jobbtid :)
> >
> > /an
>
> sch, det hr r arbetsrelaterat juh! Dessutom kan
> jag inte sova p ntterna pga detta. Och det r
> viktigt att jag sover p ntterna s jag kan jobba
> bra p dagarna ;) Vem r du frresten?
I think there's a glitch in the forum software. Is the signal coming through scrambled on anyone else's end?
:)
> I think there's a glitch in the forum software. Is
> the signal coming through scrambled on anyone else's
> end?
>
> :)
To me it doesn't look scrambled at all. I understand Swedish (some of it, at least). :-)
OleVVa at 2007-7-28 15:31:47 >

Hehe, jo det r arbetsrelaterat. Skojade lite.. Jag r en god kollega med dig :)
Message was edited by:
aname
null
anamea at 2007-7-28 15:31:47 >
