The Artima Developer Community
Sponsored Link

Legacy Java Answers Forum
September 2000

Advertisement

Advertisement

This page contains an archived post to the Java Answers Forum made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.

Message:

Can static methods use static members, which are initialized in the static block of

Posted by Tjeerd Verhagen on October 26, 2000 at 7:54 AM

Hello,


Can static methods use static members, which are initialized in the static block of
the derived class?

I would like to make something simular as the System.out functionality, which is
initilized in the static constructor block. But where the static member of the parent
class is initialized in the derived class.

See also the Main.java in which the problem is more detailed explained and 3 cases
are work out. Where case 1 is the solution I would like to make, but gives an Exception.
Case 2 and 3 are work arounds.

My question is, did I miss something? Is it allowed / corred what I would like to do or
missed I something out?

Or is it maybe a JVM bug? Tested the constuction in Sun JDK 1.1.6, 1.2.2, 1.3.


Thank you, Tjeerd


--------------------------------------------------------------------------------
Logging.java
--------------------------------------------------------------------------------
package logger;


public class Logging {
protected String name = "Unknown";

public Logging(String name) {
this.name = name;
}


public String getName() {
return this.name;
}

}

--------------------------------------------------------------------------------
AbstractLogger.java
--------------------------------------------------------------------------------
package logger;


public abstract class AbstractLogger {
protected static Logging instanceLogging = null;

//* Case 1:
public static String getName() {
return instanceLogging.name;
}
//*/

public static String getText() {
return "Some text.";
}

}

--------------------------------------------------------------------------------
MyLogger.java
--------------------------------------------------------------------------------
import logger.AbstractLogger;
import logger.Logging;


public class MyLogger extends AbstractLogger {

static {
instanceLogging = new Logging(MyLogger.class.getName());
}

/* Case 3:
public static String getName() {
return instanceLogging.getName();
}
//*/
}

--------------------------------------------------------------------------------
Main.java
--------------------------------------------------------------------------------
public class Main {

public static void main(String arg[]) {
/* Case 2:
new MyLogger();
//*/
System.out.println("MyLogger name = " + MyLogger.getName());
System.out.println("MyLogger text = " + MyLogger.getText());
}

}

/*
Why do static methods, defined in an abstract class, using static members, return NullPointerException at runtime? The used
static member should already have been constructed, in de static construction block at class loading time. But it seems not
to happen.

At compile time there are no problems, but at runtime I get a NullPointerException. I thought that the static block would
take care of initialization at the moment the class would be loaded by the ClassLoader.

Oke the cases:

Case 1:

+------------------------+ +--------------------+
| Logging | <--------- | AbstractLogger |
+------------------------+ +--------------------+
|# String name | |#S Logging logging |
|+ Logging(String name) | |+S String getName() |
|+ String getName() | +--------------------+
+------------------------+ /\
/ \
----
|
|
+----------------------------------------+ +----------------------------------+
| MyLogger | <----- | Main |
+----------------------------------------+ +----------------------------------+
|S { logging = new Logger("MyLogger"); } | |+S void Main(String args[]) { |
+----------------------------------------+ | println(MyLogger.getName()); |
| } |
+----------------------------------+

This doesn't work, will give a NullPointerException. It seems that the static constructor block (in MyLogger) is not called
before the static method (in AbstractLogger) is called.


Case 2:

+------------------------+ +--------------------+
| Logging | <--------- | AbstractLogger |
+------------------------+ +--------------------+
|# String name | |#S Logging logging |
|+ Logging(String name) | |+S String getName() |
|+ String getName() | +--------------------+
+------------------------+ /\
/ \
----
|
|
+----------------------------------------+ +----------------------------------+
| MyLogger | <----- | Main |
+----------------------------------------+ +----------------------------------+
|S { logging = new Logger("MyLogger"); } | |+S void Main(String args[]) { |
+----------------------------------------+ | new MyLogger(); |
| println(MyLogger.getName()); |
| } |
+----------------------------------+

Introducing an explisit constructor call in main, will do the needed initialization. Now everything runs without an Exception.


Case 3:

+------------------------+ +--------------------+
| Logging | <--------- | AbstractLogger |
+------------------------+ +--------------------+
|# String name | |#S Logging logging |
|+ Logging(String name) | +--------------------+
|+ String getName() | /\
+------------------------+ / \
----
|
|
+----------------------------------------+ +----------------------------------+
| MyLogger | <----- | Main |
+----------------------------------------+ +----------------------------------+
|S { logging = new Logger("MyLogger"); } | |+S void Main(String args[]) { |
|+S String getName() | | println(MyLogger.getName()); |
+----------------------------------------+ | } |
+----------------------------------+

And in this case I moved the static method getName() from the AbstractLogger class to the MyLogger class. Know it will also run
without any Exception and without the constructor in main!

*/

--------------------------------------------------------------------------------





Replies:

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us