Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Can you help me understand this Java syntax?

Options
  • 19-04-2009 7:32pm
    #1
    Closed Accounts Posts: 310 ✭✭


    HI
    Firstly sorry for not embedding the code in the thread, I was not sure how to
    I have a question about an exercise in the Sierra SCJP Java 5 book, on Inner Classes that I was hoping someone could help explain. Here is the question and answer

    public class Foo {
    Foo() {System.out.print("foo");}

    class Bar{
    Bar() {System.out.print("bar");}
    public void go() {System.out.print("hi");}
    }

    public static void main(String[] args) {
    Foo f = new Foo();
    f.makeBar();
    }

    void makeBar() {
    (new Bar() {}).go(); //syntax
    }
    }

    What is the result?
    A. Compilation fails.
    B. An error occurs at runtime.
    C. foobarhi
    D. barhi
    E. hi
    F. foohi

    Answer:
    C is correct because first the Foo instance is created, which means the Foo constructor runs and prints foo. Next, the makeBar() method is invoked, which creates a Bar, which means the Bar constructor runs and prints bar, and finally an instance is created (of an anonymous
    subtype of Bar), from which the go() method is invoked. Note that the line (new Bar() {}).go(); creates a little tiny anonymous inner class, a subtype of Bar


    Now I understand the answer but I have a question about the syntax of the line (new Bar() {}).go();. Basically I am struggling to understand why this legal. I thought that when closing off the anonymous class definition a semi colon should follow the curly brace?

    So why would the line not be something like?
    (new Bar() {}; ).go(); (note the semi colon after the closing curly brace)

    I would appreciate any hints anyone could give, thanks


Comments

  • Registered Users Posts: 3,945 ✭✭✭Anima


    If I could use this code as an example:
    [PHP]
    new Thread(new Runnable() {
    public void run() {
    try {
    while (true) {
    sleep(1000); System.out.print(".");
    }
    }
    catch(InterruptedException ex) {}
    }
    }).start();
    [/PHP]

    Thats the same as the code below pretty much
    [PHP](new Bar() {}).go();[/PHP]

    If you did it the way you mentioned, the first code would be like this:
    [PHP]
    new Thread(new Runnable() {
    public void run() {
    try {
    while (true) {
    sleep(1000); System.out.print(".");
    }
    }
    catch(InterruptedException ex) {}
    }
    };).start();
    [/PHP]

    So you're kind of prematurely ending the statement before you can execute the start() method. I may not have explained that well but thats my understanding.


  • Registered Users Posts: 1,916 ✭✭✭ronivek


    My understanding is that you're effectively instantiating a new object which implements the Bar interface; basically as if you're extending Bar().

    For example; if you were to compile and run the code with the following alteration;

    [PHP]
    void makeBar() {
    (new Bar() {
    public void go() {System.out.print("HAI");}
    }).go(); //syntax
    }

    [/PHP]

    The resulting output would be a call to the overridden method rather than the method within the superclass.

    Not sure if that makes it any clearer; it's also possible I'm on the wrong track but if that's the case I'm sure someone will elaborate!

    EDIT: It seems I may have misunderstood the actual question; the simple answer is that you're effectively declaring a new class and you don't need to delimit the end of a class definition with a semi-colon; the brace suffices.


  • Closed Accounts Posts: 310 ✭✭Annuv


    Thanks lads, it makes more sense now.

    I guess I was getting caught up on the fact that the anonymous inner class definition should be should be finished with a semi colon, but since go() is immediately invoked on the object the statement doesn't end until after the method invocation, so no semi colon until then

    Thanks again, this SCJP is no walk in the park


  • Registered Users Posts: 5,618 ✭✭✭Civilian_Target


    Some of this inner classes stuff is seriously messed up. Saw a real life example last week of someone at work declaring an annonymous inner class, implementing an interface, in a method call. I mean, you can, but why the fork would you?!


  • Moderators, Science, Health & Environment Moderators Posts: 10,079 Mod ✭✭✭✭marco_polo


    Some of this inner classes stuff is seriously messed up. Saw a real life example last week of someone at work declaring an annonymous inner class, implementing an interface, in a method call. I mean, you can, but why the fork would you?!

    The only example I can think of is it is sometimes handy for implementing event listeners in a small GUI project. But it is akward, looks terrible and pales in compared to something like delegates in .net.

    Oops re-read your post, in a method call? :confused:

    By any chance he is not one of those contractors that write the most cryptic code possible in order to keep a healthy repeat business? :)


  • Advertisement
  • Registered Users Posts: 302 ✭✭BlueSpud


    Inner classes are fine, but for fruit cake, anonymous inner classes should only be written by someone who is 100% sure that no one else will ever have to maintain the code.

    Unless you are looking for that last ounce of efficiency on a mission critical project, there is no excuse, imho.


  • Registered Users Posts: 5,618 ✭✭✭Civilian_Target


    marco_polo wrote: »
    By any chance he is not one of those contractors that write the most cryptic code possible in order to keep a healthy repeat business? :)

    Nah, he's just a code masochist. His idea of a good time is merging binary files in Clearcase. Incidentally, it tipped up a bug in Eclipse, I changed the interface signature and Eclipse did not find or change the anonymous inner classes.

    Not a Listener, but not far off... a match criteria for a strategy-pattern-based filtering engine.


Advertisement