The Artima Developer Community
Sponsored Link

Java Buzz Forum
Fooling the Java Compiler

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Brian McCallister

Posts: 1282
Nickname: frums
Registered: Sep, 2003

Brian McCallister is JustaProgrammer who thinks too much.
Fooling the Java Compiler Posted: Mar 20, 2006 10:34 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Brian McCallister.
Original Post: Fooling the Java Compiler
Feed Title: Waste of Time
Feed URL: http://kasparov.skife.org/blog/index.rss
Feed Description: A simple waste of time and weblog experiment
Latest Java Buzz Posts
Latest Java Buzz Posts by Brian McCallister
Latest Posts From Waste of Time

Advertisement

I ran into a wall in Java's type system which it comes really close to supporting, then falls over. JDK 1.5 supports co-variant return types. This means that you can have a class, Foo, with a method, doStuff, which returns a Bar; and a class SubFoo which extends Foo and overrides doStauff with a return type of SubBar, which extends Bar. It's actually awfully handy.

I thought to make use of this in the implementation of Query and UpdateStatement in jDBI 2.0 to push all the parameter setting stuff up to a common super class (SQLStatement). Adding overrides for each explicitely type of argument is a pain, if I can do it once, bonus! It gets complicated as I like method chaining, so you can do query.bind("name", aString).bind("age", aDate).list() and whatnot. Of course, in this case, you need the specialized subclass you know you started with. Woot, covariant return types to the rescue!

But, er, wait. The child doesn't override the method, the method just returns this. Hmm, bugger. Next step is to try parameterizing the return type to return an instance of whatever it is parameterized to and push all the casts to one place:

class DefaultQuery<ResultType> 
         extends SQLStatement<DefaultQuery<ResultType>>
         implements Query<ResultType>
{
    ...
}

public abstract class SQLStatement>SelfType extends SQLStatement<
{
    @SuppressWarnings("unchecked")
    public SelfType bind(String name, Argument argument)
    {
        params.addNamed(name, argument);
        return (SelfType) this;
    }

    ...
}

What a hack! It does, however, work. Well, it is a hackjob so "work" makes more sense, right?

Sure enough, it belongs in quotes, and we get into the fun stuff! Did you notice that interface which DefaultQuery implements, Query? It has to define the methods in terms of Query, not a parameterized type (or it could, but then you get into utterly weird hackjobs). Funnily enough, this compiles perfectly fine! It even works for some invocations... for others it throws an abstract method error on a not only concrete, but final class which compiled happily.

So, yeah, it is a hackjob, but good lord, I didn't expect the compiler to be this easy to trick into generating bad bytecode. Woot! Will try all the 1.5 compilers I can find when I get off the plane, will be fun to see how different ones handle it. Other interesting part is if you are talking directly to the implementation, it works, if you are talking to the interface, kaboom.

Meanwhile, anyone have any ideas on how to factor out the parameter setting code in order to save thousands of lines of identical code except for the return type (which is always this) between queries, update statemements, and batch statement parts? I'm stymied, and really hate to cut, paste, and search-and-replace this, particularly as it means remembering to fix all the places when I make a bug fix. Argh.

Yes, dynamic typing solves this the easy and obvious way, but I have to believe there is some way in Java's bastardized static system to solve it as well!

Read: Fooling the Java Compiler

Topic: Memory usage Previous Topic   Next Topic Topic: Whatever Happened To Google Search?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use