Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Java (http://www.velocityreviews.com/forums/f30-java.html)
-   -   How to call an instance method from a static method allowing overrides? (http://www.velocityreviews.com/forums/t123959-how-to-call-an-instance-method-from-a-static-method-allowing-overrides.html)

=?ISO-8859-1?Q?Thomas_Gagn=E9?= 07-02-2003 03:57 AM

How to call an instance method from a static method allowing overrides?
 
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 07-02-2003 05:57 AM

Re: How to call an instance method from a static method allowing overrides?
 
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é" <tgagne@wide-open-west.com> wrote in message news:3F025838.8030103@wide-open-west.com...
> 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
>




Tobias Noebel 07-02-2003 07:44 AM

Re: How to call an instance method from a static method allowing overrides?
 
Hi Thomas,

Thomas Gagné <tgagne@wide-open-west.com> 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.

=?ISO-8859-15?Q?Thomas_Gagn=E9?= 07-02-2003 12:59 PM

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


Karl von Laudermann 07-02-2003 01:17 PM

Re: How to call an instance method from a static method allowing overrides?
 
Thomas Gagné <tgagne@wide-open-west.com> wrote in message news:<3F025838.8030103@wide-open-west.com>...
> 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.

Roedy Green 07-02-2003 02:18 PM

Re: How to call an instance method from a static method allowing overrides?
 
On Wed, 02 Jul 2003 08:59:12 -0400, Thomas Gagné
<tgagne@wide-open-west.com> 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.

John C. Bollinger 07-02-2003 05:43 PM

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
jobollin@indiana.edu


Tobias Noebel 07-02-2003 06:02 PM

Re: How to call an instance method from a static method allowing overrides?
 
Thomas Gagné <tgagne@wide-open-west.com> 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. -

=?ISO-8859-15?Q?Thomas_Gagn=E9?= 07-02-2003 06:39 PM

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


Jezuch 07-02-2003 11:04 PM

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



All times are GMT. The time now is 06:43 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.