0

I Have three classes

  1. StaticHolder.java - Which holds a static variable.
  2. StaticInitializer.java -Responsible only for initializing the variable through a static method.
  3. Application.java - Retrieves the static variables value through getter method.

I thought initializing a static variable once in JVM will not go until we stop the JVM. So I called ran StaticInitializer once which will do the initialization. And tired to access its value from another class which is not working and returning null. Can anyone explain why. Thanks In Advance.

public class StaticHolder {
    private static String hello;

    public static void ini() {
        hello = "Hello World";
    }

    public static String getHello() {
        return hello;
    }

    public static void setHello(String hello) {
        StaticHolder.hello = hello;
    }
}

class StaticInitializer {
    public static void main(String[] args) {
        StaticHolder.ini();
        while (true) {
            Thread.sleep(1000);
        }
    }
}

public class Application {
    public static void main(String[] args) {
        System.out.println(StaticHolder.getHello());
    }
}
cgeek
  • 55
  • 9
  • You can only run one main method. – Steve Smith Mar 17 '17 at 10:38
  • 1
    why do you think two seperate `main` methods will run within the same JVM when started after each other? – SomeJavaGuy Mar 17 '17 at 10:39
  • Java program only supposed to have one `main` method, so either `StaticInitializer` called or `Application`, not both. – M. Prokhorov Mar 17 '17 at 10:39
  • @SomeJavaGuy I don't actually understand.But I have only one jvm instance running in my machine. – cgeek Mar 17 '17 at 10:51
  • @cgeek i guess you mean one `java` installation, a `JVM` is the thing a `java` programm will be executed in when you execute a java programm. And as you call the first main -> one `JVM` executes it, and terminates, you call the second `main`, another `JVM` executes it and terminates, not knowing anything the previous `JVM` did set variable wise. – SomeJavaGuy Mar 17 '17 at 10:53
  • @SomeJavaGuy I have edited the question. The thread which initialize will not get terminated.But the standalone program trying to get access as you say might run on different JVM how do i get value from the JVM the thread is running.Thanks in Advance. – cgeek Mar 17 '17 at 11:14

3 Answers3

2

static does not mean that this value is there forever!

It is only theree for the current java session.

Invocing the java command at the command line starts a new java session where the value needs to be initialized again.


Actually I have a daemon thread which does the initialization and stays alive.And I have another stand alone java program which tries to get the value.

Without knowing that other code involved my gueass is that you did not establish inter process communication.

The easiest way it that you "deamon" opens a server socket and your "stand alone java program" connects to it an queries the desired data through it.

Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
  • Actually I have a daemon thread which does the initialization and stays alive.And I have another stand alone java program which tries to get the value.By your answer I understand my stand alone program creates a new java session.But how do I get value from the session that daemon thread opened. – cgeek Mar 17 '17 at 11:01
  • Maybe you add the code that deamon and the other program too? – Timothy Truckle Mar 17 '17 at 11:12
  • Unfortunately I cannot add the exact code.But I have edited the question to similar scenario. Thanks. – cgeek Mar 17 '17 at 11:16
  • I understand now. Invocing java command creates a new JVM process and the static value is within that process itself.And In my program the Application.java creates a new JVM process and tries to access value form another process.Which is not possible without enabling inter-process communication.Thank you. – cgeek Mar 17 '17 at 11:56
1

So there is only one main method that can be executed as entry point for the entire application for each JVM run.

When the JVM is executed you can specify which class has to be loaded at start. The Classloader take care to load that class and then the JVM can execute the only one public static void main(String[] args) method.

In Java you need to have at least one class with a public static method named main. I suggest to read this post to understand why it is public static.

The Java Classloader is a part of the Java Runtime Environment that dynamically loads Java classes into the Java Virtual Machine. Usually classes are only loaded on demand.

So returning to your question, given that when Application.main is running there is no way to execute StaticHolder.init(), I suggest to change your main in this way:

public class Application {
    public static void main(String[] args) {
        StaticHolder.init();
        System.out.println(StaticHolder.getHello());
    }
}

or change StaticHolder in this way and remove the init:

public class StaticHolder {
    private static String hello;

    static {
        hello = "Hello World";
    }

    public static String getHello() {
        return hello;
    }

    public static void setHello(String hello) {
        StaticHolder.hello = hello;
    }
}

On the other hand, just to be clear if you run the StaticInitializer.main this has no effect on Application.main execution.

Community
  • 1
  • 1
freedev
  • 25,946
  • 8
  • 108
  • 125
  • 2
    I think we should also explain why is running `java StaticInitializer.java` has no effect when running `java Application.java` right after (classloading, etc.) can you also mention that? – M. Prokhorov Mar 17 '17 at 10:40
  • @M.Prokhorov Right I'll do immediately – freedev Mar 17 '17 at 10:43
0

In your program , when main method of StaticInitializer is first executed, a String named hello is initalized. and as ini() method is called, the value 'Hello world' is assigned to hello. Then jvm exists main method, and then stops working. Again when we compile application class,instead of the previous hello variable , a new hello string variable is created with no value assigned(null valued) . That's why you're getting null as output. Thankyou.

  • The actual problem is I have a daemon thread which does the initialization and stays alive.And I have another stand alone java program which tries to get the value. I can reinitialize as you suggests but I don't understand why it is becoming null. – cgeek Mar 17 '17 at 10:55