From: Ross on
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
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
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
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
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