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:
|