• Post Reply Bookmark Topic Watch Topic
  • New Topic

Generics and String.compareTo()  RSS feed

 
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In Tiger, String implements Comparable<String> . This means that instead of compareTo(Object), String has a compareTo(String) method. I've observed that older code along the lines of

Object o = ...
String s = ...
int result = s.compareTo(o);

won't actually compile under Tiger, and indeed, if you disassemble Tiger's java/lang/String.class, you find that the class file really doesn't contain the compareTo(Object) method -- only compareTo(String). Of course, you can force the old source to compile with "-source 1.4", or you can change the old source to add a cast to String; either of these fixes the compilation problem.

But the interesting observation is that if you compile the old code with an old compiler, it will run just fine on the Tiger JVM. The old code will contain a hard-coded reference to compareTo(Ljava/lang/Object;)I, but that method doesn't actually exist. Somehow, the JVM knows to convert the method signature here.

This isn't erasure, in which what appears in the compiled code has types stripped away. This is a runtime transformation of some kind. What's the general principle? Anybody know how it's implemented? I can't find an explanation of this anyplace. In fact, Gilad Bracha's July, 2004 article seems to make a big deal about something very similar to this in section 10, but makes it out to be the API developer's responsibility to do the right thing -- and that thing hasn't been done here, but things still work.
[ October 26, 2005: Message edited by: Ernest Friedman-Hill ]
 
author
Sheriff
Posts: 14112
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you sure it isn't erasure? My wild guess would be that the compareTo(String) method actually compiles to compareTo(Object) byte code. After all, if it didn't, compareTo wouldn't be polymorphic anymore...
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ilja Preuss:
My wild guess would be that the compareTo(String) method actually compiles to compareTo(Object) byte code.


No, it doesn't. That's the freaky thing. I looked with javap, and I also looked with "Jad", which is old enough that it doesn't know anything about Tiger. Both claim there's a compareTo(String) method in there, and no compareTo(Object). Try it yourself!
 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My observations suggest that two methods are created.
Given:

produces:

...on Windows 2000.

The design flaw in the Comparable interface is that it should be interface Comparable<T>{int compareTo(T t);} Of course, this would break reverse compatibility, and also is impossible. The same reasoning can be applied to the Object.equals and hashCode methods.
interface Equalable<T>{boolean isEqual(T t1, T t2);} interface HashCodeable<T>{int getHashCode(T t);} are much preferred. Unfortunately, the core API does not permit this detached coupling. Luckily, Comparable has a Comparator in places where the core API demands one or the other.

One day, someone might write an API that fixes all this mess such that it highlights these flaws a bit better than my rantings attempt
 
Ernest Friedman-Hill
author and iconoclast
Sheriff
Posts: 24217
38
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah. you're right, Tony. I didn't see them both in the javap output for String. I saw the first one, and didn't notice the generated method later on in the output:



OK, so that's the trick. The compiler generates a compatibility method. Here's the diassembly for the extra method, by the way; it just forwards to the hand-written method that satisfies Comparable<String>

 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!