[java] Weird code trick (inner class, presumably)

Started by
19 comments, last by GameDev.net 19 years, 4 months ago
I found this piece of code in a J2ME project I inherited. The whole thing was written by a person who apparently never heard of arrays and switch/case statements and was generally a horribly inefficient and sloppy coder. Also, the file had some incorrectly nested inner classes, horrid indentation, etc. Hence, I am not sure what to think of the following piece of code. Honestly - it compiles! So, could any of you Java veterans tell me what he's doing from a syntactic perspective, and what will happen during compilation of said code snippet? And, does it actually work the way it's intended to (apparently call method setStart() three seconds later)? [Edited by - Thygrrr on November 27, 2004 8:38:09 AM]
Advertisement
Quote:Original post by Thygrrr

Honestly - it compiles!


It's ugly, but yes it works as designed. One thing I had trouble when transferring over from C++ was the concept of java being able to override and create classes on the fly. So what he's actually doing there is creating a new TimerTask, and overriding its run() method on the fly. So what he's getting there is a one-use class that is important enough to be needed, but not important enough to be given its own class file. This is common for a class that you're only going to need ONE TIME, for ONE THING. Java lets you do this, as strange as it is to the C++ brain. :-) Maybe my comments will explain better.

public void startTimer() {    TimerTask task = new TimerTask() {        // thanks to Java, we can override the run()        // method (or whatever else we wanted to)        // for this specific implementation of TimerTask        // on the fly.        public void run() {            // in this particular case, we modify it because            // we want this particular breed of TimerTask to            // call setStart() whenever it runs (whatever this            // does) instead of its usual behaviour            setStart();        }    }; // there - done. The rest of the TimerTasks in the    // source code, globally, will behave as normal. Only this    // one will be effected.    timer = new Timer();    timer.schedule(task, 3000); // schedule it to do whatever it    // does, and do it every 3000 milliseconds}


Hope that helped

(edit: I personally think that this is *horrendous* coding style and should be avoided at just about all costs... it makes code damn near impossible to read, even when you know what you're looking at. But to each their own.)
=========================Buildium. Codium. Fragium.http://www.aklabs.net/=========================
Wow, thanks for the really detailed reply. I think overriding classes on the fly might be a little similar to lambda functions in Python (and originall, FORTRAN, wasn't it?). Little throwaway objects.

I think these might come in handy for quick tests, but generally, I'D stay away from then. That code is damn near impossible to read, and the first thign you expect is that someone accidentally copy/pasted something into a block in the wrong place.

Will this coding 'technique' result in an additional .class file being generated?

(and, for laughs: a snippet from the same source file)

Of course I decided to rewrite this mess from scratch... :p~
My god, whose source code are you taking over? Bill gates?

No, there won't be an additional .class file generated - this is all handled at runtime. There will be an object of appropriate size created on the heap, tho.

No prob about the reply. I tend to be very long-winded, and unable to compress my descriptions.

cat andrew | tar --create --gzip > just_shutup.tgz
=========================Buildium. Codium. Fragium.http://www.aklabs.net/=========================
What he is doing there is call an anonymous class. It is created on the fly for use in that one location. It does have its uses, but I tend to avoid it because it does make code harder to read.

Quote:Original post by andrewk3652
No, there won't be an additional .class file generated - this is all handled at runtime. There will be an object of appropriate size created on the heap, tho.


Wrong. There will be a class file generated for each anonymous class used. If that example were in a file call Test.java, then Test.class and Test$1.class will be generated.
"None of us learn in a vacuum; we all stand on the shoulders of giants such as Wirth and Knuth and thousands of others. Lend your shoulders to building the future!" - Michael Abrash[JavaGaming.org][The Java Tutorial][Slick][LWJGL][LWJGL Tutorials for NeHe][LWJGL Wiki][jMonkey Engine]
Quote:Wrong. There will be a class file generated for each anonymous class used. If that example were in a file call Test.java, then Test.class and Test$1.class will be generated.


I stand corrected
=========================Buildium. Codium. Fragium.http://www.aklabs.net/=========================
Quote:Original post by CaptainJester
Wrong. There will be a class file generated for each anonymous class used. If that example were in a file call Test.java, then Test.class and Test$1.class will be generated.


Thanks for clearing that up :)

Yes, anonymous class as in anonymous function. I hope to remember this term for future reference! Thanks to all of you.

And no, the code wasn't written by Bill Gates, haha! (I actually estimate Billy to be at least a somewhat decent coder, at least with regard to BASIC in the late 70s!)
Quote:Original post by Thygrrr
Wow, thanks for the really detailed reply. I think overriding classes on the fly might be a little similar to lambda functions in Python (and originall, FORTRAN, wasn't it?). Little throwaway objects.


Well, you *can* look at it like that. I'm not sure whether it's helpful though - could easily be even more confusing. It would be theoretically possible to use them in that way.

Quote:
I think these might come in handy for quick tests, but generally, I'D stay away from then.


Most people steer clear of all inner classes, especially anon ones, although Sun rather likes inner classes now (superset of anon classes), and has adopted them more and more in recent years. Have a look around Java2D...

Quote:
That code is damn near impossible to read, and the first thign you expect is that someone accidentally copy/pasted something into a block in the wrong place.


Just because it's syntax YOU don't see very often doesn't mean that. The syntax is very clear, if you know java syntax well. IMHO, the fact that it's used so rarely means most people don't get enough practice with them, and personally I forget the syntax each time I need to do one, so I usually just don't bother - it's too much hassle getting out the JLS :(.

Quote:
(and, for laughs: a snippet from the same source file)


What's sad is that they apparently wrote it all by hand (individual indents). I've seen perl programmers (and users of e.g. PFE, with it's powerful macros) generate java source code to do similar stuff in seconds, but doing it by hand is extra stupid - bad code AND a waste of your time :).
FORTRAN did not have lamdas; FORTRAN is as static as a language can get. I believe lambdas (a k a closures) were introduced with the whole functional programming revolution; LISP and PL/1 and Haskell and all that.
enum Bool { True, False, FileNotFound };
INNER CLASSES:
I personally dislike them. Apparently a large bunch of J2ME coders uses them, but I believe that inner classes prevent code reuse, make the code difficult to read, harder to write, and are often misused. This will result in no gain whatsoever. The actual motivation for the J2ME people I talked to was to use inner classes to cut down on the number of .class files in the .jar - I still don't know whether that's entirely possible.


FORTRAN vs LISP:
Yeah, LISP. My bad. I thought "Was it LISP? Don't really know what it is, and lambda sounds scientific. Probably has to do with FORTRAN, then, because I at least basically know what FORTRAN stands for". Thanks for straightening it out. I only know lambdas from Python.

But I did bother to check ("wasn't it?") :)

This topic is closed to new replies.

Advertisement