Prev: in the Observer (Publish/Subscribe) pattern, are notificationsalien method calls?
Next: Using 'final' with local variables
From: Ross on 14 Sep 2009 10:32 Thanks, but that doesn't quite work as intended. I have written two classes: public class Test { public static void main( String args[] ) { Thread mainThread = Thread.currentThread(); StackTraceElement[] currentStack = mainThread.getStackTrace(); StackTraceElement mainStackElement = currentStack [ currentStack.length - 1 ]; System.out.println( "My main class is " + mainStackElement.getClassName() ); } } That works fine if I run it, and reports the class as "Test". But I then create a child class. public class Test2 extends Test { } If I then run: $ java Test2 I get the output: My main class is Test When what I want is: My main class is Test2 Any ideas on how to find out the name of the executed class rather than the ancestor class which has the main method?
From: Leif Roar Moldskred on 14 Sep 2009 10:48 Ross <rossclement(a)gmail.com> wrote: > Thanks, but that doesn't quite work as intended. I have written two > classes: > > public class Test > { > public static void main( String args[] ) > { > Thread mainThread = Thread.currentThread(); > StackTraceElement[] currentStack = mainThread.getStackTrace(); > StackTraceElement mainStackElement = currentStack > [ currentStack.length - 1 ]; > > System.out.println( "My main class is " + > mainStackElement.getClassName() ); > } > } > > That works fine if I run it, and reports the class as "Test". But I > then create a child class. > > public class Test2 extends Test > { > } > > If I then run: > > $ java Test2 > > I get the output: > > My main class is Test > > When what I want is: > > My main class is Test2 > > Any ideas on how to find out the name of the executed class rather > than the ancestor class which has the main method? Ow. Don't do that. For one thing, I don't think there _is_ any way to retrieve the name of the class mentioned on the command line in this case. More importantly, it's bad design. I'd recommend you make an inherited business method, then write explicit main methods for all the classes that will use it (There can't be _that_ many of them, and it make it a lot easier to understand what's happening.) Something like this: public abstract class BaseClass { protected void doStuff( String[] args ) { // Do whatever you're supposed to do } } public class SubClass extends BaseClass { public static void main( String[] args ) { BaseClass myFoo = new SubClass( ); myFoo.doStuff( args ); } } If you have common initialization that needs to be done, use an inherited initialization method as well: public static void main( String[] args ) { BaseClass myFoo = new SubClass( ); myFoo.initialize( args ); myFoo.doStuff( ); } -- Leif Roar Moldskred
From: Ross on 14 Sep 2009 10:54 I could probably solve the problem if I could find a list of the classes that are currently loaded. As only one of them will be an instance of "Game", apart from "Game" (my parent class) itself. But looking through the classloader interface, I can't seem to find that out either.
From: Ross on 14 Sep 2009 11:02 On Sep 14, 3:48 pm, Leif Roar Moldskred <le...(a)huldreheim.homelinux.org> wrote: > Ow. Don't do that. For one thing, I don't think there _is_ any way > to retrieve the name of the class mentioned on the command line > in this case. More importantly, it's bad design. > > I'd recommend you make an inherited business method, then write > explicit main methods for all the classes that will use it (There > can't be _that_ many of them, and it make it a lot easier to > understand what's happening.) > > Something like this: > > public abstract class BaseClass { > protected void doStuff( String[] args ) { > // Do whatever you're supposed to do > } > > } > > public class SubClass extends BaseClass { > public static void main( String[] args ) { > BaseClass myFoo = new SubClass( ); > myFoo.doStuff( args ); > } > > } > > If you have common initialization that needs to be done, use an > inherited initialization method as well: > > public static void main( String[] args ) { > BaseClass myFoo = new SubClass( ); > myFoo.initialize( args ); > myFoo.doStuff( ); > } Unfortunately, I need to do this. The parent class is going to be subclassed by young children, first experimental subject being a nine year old. I have to kick out the main class, but still have it runnable. Fundamentally, you can't teach advanced programming languages with sophisticated structures to young children, or at least most young children. I'm sure there are some prodigies out there. Previously when I've done this before, I've created bespoke programming languages with bespoke IDEs. But the whole point of what I'm trying now is to see whether Object Orientated Programming can be leveraged to produce a LOGO style language (and execution environment) while the code being written is actually proper Java, just extending a prewritten class. The alternative is to modify the IDE that will be used to supply the name of the class as the first argument to the running program. I don't particularly want to modify the IDE, as that means that the IDE would become a necessary part of the environment, but it is currently the best solution, and I don't appear to be finding anything better than that. Thanks for all for the comments and ideas.
From: Alessio Stalla on 14 Sep 2009 11:02
On Sep 14, 4:54 pm, Ross <rossclem...(a)gmail.com> wrote: > I could probably solve the problem if I could find a list of the > classes that are currently loaded. As only one of them will be an > instance of "Game", apart from "Game" (my parent class) itself. But > looking through the classloader interface, I can't seem to find that > out either. If only one game at a time can be loaded (this wasn't apparent from your first post), you can use a factory to create it. E.g. you can use the standard service provider machinery: <http://java.sun.com/j2se/1.3/ docs/guide/jar/jar.html#Service%20Provider> or a custom solution. hth, Alessio |