How to call an instance method from a static method allowing overrides?

Discussion in 'Java' started by =?ISO-8859-1?Q?Thomas_Gagn=E9?=, Jul 2, 2003.

  1. I'd like to be able to subclass a class with "public static main(String
    argv[])" but since static methods can't be overridden I want it first to get
    an instance of itself then call the instance's main().

    Problem is, how does the class reference itself without naming itself?
    --
    ..tom
    remove dashes in email for replies
    http://isectd.sourceforge.net
    =?ISO-8859-1?Q?Thomas_Gagn=E9?=, Jul 2, 2003
    #1
    1. Advertising

  2. public class ClassName {
    // JDK 1.4
    static String className = new Throwable().getStackTrace()[0].getClassName();
    public static void main(String[] args) {
    System.out.println(className);
    // now you have class name in static context
    // maybe you can use Class.forName() to get the Class and then call methods
    // using reflection

    }
    }

    "Thomas Gagné" <> wrote in message news:...
    > I'd like to be able to subclass a class with "public static main(String
    > argv[])" but since static methods can't be overridden I want it first to get
    > an instance of itself then call the instance's main().
    >
    > Problem is, how does the class reference itself without naming itself?
    > --
    > .tom
    > remove dashes in email for replies
    > http://isectd.sourceforge.net
    >
    Sandip Chitale, Jul 2, 2003
    #2
    1. Advertising

  3. Hi Thomas,

    Thomas Gagné <> schrieb am Tue, 01 Jul 2003
    23:57:44 -0400:
    >
    > I'd like to be able to subclass a class with "public static main(String
    > argv[])" but since static methods can't be overridden I want it first to
    > get an instance of itself then call the instance's main().
    >
    > Problem is, how does the class reference itself without naming itself?
    >


    I hope I understood your problem:
    You want to call "java A", but want to extend A with class B, and somehow
    get B.main() called (first)?

    First of all you can override a static method (as long as it is not final),
    the Swing-UI uses this for creating ComponentUIs.

    But this doesn't help much in your case, due to the fact, that you call a
    static method on a class:
    A.main();
    And whatever class extends A, because main() is static linked there is no
    possibility to get even knowledge from A, which classes are extending A.
    Assume there are two classes B and C extending A. How should A (or java)
    know, that you mean B.main() instead of C.main()?

    On the other hand, if you call "java B", then you can write a new static
    main() in class B calling the super main() of class A by A.main(), and it
    will work fine.

    Tobias Nöbel

    p.s. With respect to Sandip, but his suggestion wont work because className
    would linked static to ClassName.
    Tobias Noebel, Jul 2, 2003
    #3
  4. Re: How to call an instance method from a static method allowingoverrides?

    I want to create a class that has all my favorite behavior for headless
    applications. I want it to do all the desired stuff when my applications
    start-up. We'll call this EfiMain

    1 public class EfiMain {
    2 public static void main(String argv[]) {
    3 EfiMain anEfiMain;
    4 // do some startup stuff for my apps.
    5 anEfiMain := new EfiMain();
    6 anEfiMain.main(argv);
    7 }
    8 }
    9
    10 public class EfiEcho extends EfiMain {
    11 public void main(String argv[]) {
    12 System.out.println(argv);
    13 }

    After compiling both classes if I run "java EfiEcho" how would EfiEcho ever
    run since the static main() in EfiMain doesn't know the name of the subclass
    to create. It would have to figure that out at runtime.

    I suspect the static main() in EfiMain will run because it's not overridden in
    EfiEcho, but how would it know that the instance it's supposed to create is an
    EfiEcho and not an EfiMain? Looking at the command line might be one way but
    that's cheating.

    I guess I'm looking for a corallary to Smalltalk's "self new" which when run
    from a class (static) method will create an instance of whichever subclass the
    message was sent to.

    My next question will be about invoking super methods, but I'll read more of
    Bruce Eckel's book before asking that.

    Tobias Noebel wrote:
    >
    > I hope I understood your problem:
    > You want to call "java A", but want to extend A with class B, and
    > somehow get B.main() called (first)?
    >
    > First of all you can override a static method (as long as it is not
    > final), the Swing-UI uses this for creating ComponentUIs.
    >
    > But this doesn't help much in your case, due to the fact, that you call
    > a static method on a class:
    > A.main();
    > And whatever class extends A, because main() is static linked there is
    > no possibility to get even knowledge from A, which classes are extending
    > A. Assume there are two classes B and C extending A. How should A (or
    > java) know, that you mean B.main() instead of C.main()?
    >
    > On the other hand, if you call "java B", then you can write a new static
    > main() in class B calling the super main() of class A by A.main(), and
    > it will work fine.


    --
    ..tom
    remove dashes in email for replies
    http://isectd.sourceforge.net
    =?ISO-8859-15?Q?Thomas_Gagn=E9?=, Jul 2, 2003
    #4
  5. Thomas Gagné <> wrote in message news:<>...
    > I'd like to be able to subclass a class with "public static main(String
    > argv[])" but since static methods can't be overridden I want it first to get
    > an instance of itself then call the instance's main().


    There's no such thing as "the instance's main()". main() belongs to a
    class, and has no inherent relationship with any instance of that
    class, even when called using an object rather than the class name. In
    fact, no such instance even exists when your program starts running.
    The only way to "get" an instance of the class is to create one.

    I tend to write main() methods that do little more than allocate a new
    instance of the containing class, and then call a non-static method on
    that instance to do all of the real work. It sounds to me like you
    might want to do the same thing here.

    class A
    {
    public static main (String argv[])
    {
    A myObj = new A();
    myObj.doStuff();
    }

    protected void doStuff()
    {
    // Actual program implementation
    }
    }

    Now you can have all of your program logic in non-static methods,
    which a subclass can override and call from its main() method.
    Karl von Laudermann, Jul 2, 2003
    #5
  6. =?ISO-8859-1?Q?Thomas_Gagn=E9?=

    Roedy Green Guest

    On Wed, 02 Jul 2003 08:59:12 -0400, Thomas Gagné
    <> wrote or quoted :

    >I guess I'm looking for a corallary to Smalltalk's "self new" which when run
    >from a class (static) method will create an instance of whichever subclass the
    >message was sent to.


    There is clone, but it is protected. You have to manually write a
    public wrapper for it every time you want to actually use it.

    see http://mindprod.com/jgloss/clone.html

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, Jul 2, 2003
    #6
  7. Re: How to call an instance method from a static method allowingoverrides?

    Thomas Gagné wrote:
    > I want to create a class that has all my favorite behavior for headless
    > applications. I want it to do all the desired stuff when my
    > applications start-up. We'll call this EfiMain
    >
    > 1 public class EfiMain {
    > 2 public static void main(String argv[]) {
    > 3 EfiMain anEfiMain;
    > 4 // do some startup stuff for my apps.
    > 5 anEfiMain := new EfiMain();
    > 6 anEfiMain.main(argv);


    This is broken (as perhaps you know) because it will always invoke
    EfiMain.main, even if anEfiMain is actually an instance of an EfiMain
    subclass. It also creates an efiMain instance (or, if there were a way
    to do what you actually want, a subclass instance) which it then
    discards without using. That's right, without using. Invocation of
    static methods "on" instances does not actually use the instances at
    all, only the compile-time type of the references. That is one reason
    why that mode of static method invocation is recommended against by many
    experienced programmers, including several in this forum.

    > 7 }
    > 8 }
    > 9
    > 10 public class EfiEcho extends EfiMain {
    > 11 public void main(String argv[]) {
    > 12 System.out.println(argv);
    > 13 }
    >
    > After compiling both classes if I run "java EfiEcho" how would EfiEcho
    > ever run since the static main() in EfiMain doesn't know the name of the
    > subclass to create. It would have to figure that out at runtime.


    You are going about it the wrong way. If you run "java EfiEcho" then
    EfiEcho.main will always be invoked (first). If you want to run the
    superclass' main as well then you can easily do so from the subclass'
    main because there you know the name of the superclass. (Example below.)

    > I suspect the static main() in EfiMain will run because it's not
    > overridden in EfiEcho, but how would it know that the instance it's
    > supposed to create is an EfiEcho and not an EfiMain? Looking at the
    > command line might be one way but that's cheating.


    No, if you run "java EfiEcho" then it is EfiEcho.main that is run by the
    VM. The existence of EfiMain.main is irrelevant here. Also, you cannot
    cheat by looking at the command line because unlike in C / C++ / *NIX
    shells, only the arguments to the application (everything _after_ the
    class name) are provided in the argument to main(String[]).

    > I guess I'm looking for a corallary to Smalltalk's "self new" which when
    > run from a class (static) method will create an instance of whichever
    > subclass the message was sent to.


    This is not possible in Java because static methods only have the
    context of their declaring class available. Either through programmer
    knowledge or through reflection static methods can use their class'
    superclass, but they cannot obtain subclass information either way.

    > My next question will be about invoking super methods, but I'll read
    > more of Bruce Eckel's book before asking that.


    Here is an example that shows how you might do what you want:


    public class EfiMain {

    public static void main(String[] args) {
    // do common startup stuff
    }
    }

    public class EfiEcho extends EfiMain {
    public static void main(String[] args) {
    EfiMain.main(args);
    // do stuff specific to EfiEcho
    }
    }


    Note that the two classes must be in separate files if, as above, they
    are both public. Also note that the above example in no way depends on
    EfiEcho being a subclass of EfiMain, or on EfiMain.main's specific name
    or signature. If EfiMain is not an application in its own right then
    some other name should probably be chosen.


    John Bollinger
    John C. Bollinger, Jul 2, 2003
    #7
  8. Thomas Gagné <> schrieb am Wed, 02 Jul 2003
    08:59:12 -0400:

    > I want to create a class that has all my favorite behavior for headless
    > applications. I want it to do all the desired stuff when my
    > applications start-up. We'll call this EfiMain
    >
    > 1 public class EfiMain {
    > 2 public static void main(String argv[]) {
    > 3 EfiMain anEfiMain;
    > 4 // do some startup stuff for my apps.
    > 5 anEfiMain := new EfiMain();
    > 6 anEfiMain.main(argv);
    > 7 }
    > 8 }
    > 9
    > 10 public class EfiEcho extends EfiMain {
    > 11 public void main(String argv[]) {
    > 12 System.out.println(argv);
    > 13 }
    >



    Ok, here is one suggestion:

    public class EfiMain {

    public static void main(String argv) {
    main(new EfiMain(), argv);
    }

    public static void main(EfiMain mainObject, String[] argv) {
    // do some startup stuff for my apps.
    anEfiMain.init(argv);
    }
    public void init(String argv[]) {
    // All extra stuff
    }

    }

    public class EfiEcho extends EfiMain {
    public static void main(String[] argv) {
    main(new EfiEcho(), argv);
    }

    public void init(String argv[]) {
    System.out.println(argv);
    }
    }


    Here is another - better, more Java-like:

    public class EfiMain {

    public static void main(String argv) {
    new EfiMain(argv);
    }

    public EfiMain(String[] argv) {
    // do some startup stuff for my apps.
    anEfiMain.init(argv);
    }
    public void init(String argv[]) {
    // All extra, maybe unnecessary stuff
    }

    }

    public class EfiEcho extends EfiMain {

    public static void main(String[] argv) {
    new EfiEcho(argv);
    }

    public EfiEcho(String[] argv) {
    super(argv);
    }

    public void init(String argv[]) {
    // My extra stuff
    System.out.println(argv);
    }
    }

    I hope it's clear why, if not, just ask.

    Tobias Noebel

    --
    - Programmieren ist wie Romanschreiben. Erst -
    - denkt man sich ein paar Typen aus, und dann -
    - muß man sehen, wie man mit ihnen zurechtkommt. -
    Tobias Noebel, Jul 2, 2003
    #8
  9. Re: How to call an instance method from a static method allowingoverrides?

    I think I'm straightened out. Thanks.

    Tobias Noebel wrote:
    <snip>
    >
    > Ok, here is one suggestion:
    >
    > public class EfiMain {
    >
    > public static void main(String argv) {
    > main(new EfiMain(), argv);
    > }
    >
    > public static void main(EfiMain mainObject, String[] argv) {
    > // do some startup stuff for my apps.
    > anEfiMain.init(argv);
    > }
    > public void init(String argv[]) {
    > // All extra stuff
    > }
    >
    > }
    >
    > public class EfiEcho extends EfiMain {
    > public static void main(String[] argv) {
    > main(new EfiEcho(), argv);
    > }
    >
    > public void init(String argv[]) {
    > System.out.println(argv);
    > }
    > }
    >
    >
    > Here is another - better, more Java-like:
    >
    > public class EfiMain {
    >
    > public static void main(String argv) {
    > new EfiMain(argv);
    > }
    >
    > public EfiMain(String[] argv) {
    > // do some startup stuff for my apps.
    > anEfiMain.init(argv);
    > }
    > public void init(String argv[]) {
    > // All extra, maybe unnecessary stuff
    > }
    >
    > }
    >
    > public class EfiEcho extends EfiMain {
    >
    > public static void main(String[] argv) {
    > new EfiEcho(argv);
    > }
    >
    > public EfiEcho(String[] argv) {
    > super(argv);
    > }
    >
    > public void init(String argv[]) {
    > // My extra stuff
    > System.out.println(argv);
    > }
    > }
    >
    > I hope it's clear why, if not, just ask.
    >
    > Tobias Noebel
    >



    --
    ..tom
    remove dashes in email for replies
    http://isectd.sourceforge.net
    =?ISO-8859-15?Q?Thomas_Gagn=E9?=, Jul 2, 2003
    #9
  10. =?ISO-8859-1?Q?Thomas_Gagn=E9?=

    Jezuch Guest

    Re: How to call an instance method from a static method allowingoverrides?

    U¿ytkownik Roedy Green napisa³:
    >>static String className = new Throwable().getStackTrace()[0].getClassName();

    >
    > You can discover the Class corresponding to any object with
    > dog.getClass(). It works on "this" too with this.getClass().


    Won't work in this case because 'this' doesn't exist in static context.
    --
    Ecce Jezuch
    "Science has failed our world
    Science has failed our mother Earth" - S. Tankian
    Jezuch, Jul 3, 2003
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page