当我尝试在另一个类中访问它时,为什么静态变量为null?

时间:2013-06-07 06:41:56

标签: java android null static-methods static-variables

我有两个类:Server类(普通java类)和MainActivity类(android活动类)。我试图使用我的MainActivity从Server类访问静态变量,但每次我尝试使用静态变量时,它总是返回null。

这是我的Server类代码:

public class Server {

  private static String clientMsg;

  public static String getClientMsg() {
      return clientMsg;
  }

  public static void main(String[] args){

    /*Some Server code here*/

    while(true){
        try {
            clientSocket = serverSocket.accept();

            //READ THE MESSAGE SENT BY CLIENT
            dataInputStream = new DataInputStream(clientSocket.getInputStream());

            //Here is where I assigned the static variable clientMsg
            clientMsg = dataInputStream.readUTF();

            dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
            dataOutputStream.writeUTF("Message Received!");

        } catch (IOException e) {
            e.printStackTrace();
        }

   /* Rest of the code here */
  }
 }
}

以下是我的MainActivity类代码:

public class MainActivity extends FragmentActivity implements LocationListener{
  private Button connect;
  /*Some variable declarations here*/

  @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main); 

      connect = (Button) findViewById(R.id.connect);

      /*Some code here*/

      connect.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String msg = Server.getClientMsg();
                if(msg != null)
                    Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
                else
                    Toast.makeText(MainActivity.this, "Client Message is null!", Toast.LENGTH_LONG).show();
            }
        });
    /*Rest of the code here*/
  }
}

无论我如何从服务器类访问静态变量 clientMsg ,它始终返回null。

我在代码中做错了吗?我应该如何访问静态变量?或者它甚至不必是静态的,我如何只是访问变量 clientMsg 而不返回空值?

/ 修改 /

很抱歉我的问题不明确。我实际上是分别运行2个类,一个是在控制台中显示的普通Java,另一个在Android模拟器中显示,最后,我在我的Android手机中运行了一个客户端应用程序。

基本上,我使用客户端应用程序向服务器发送消息,该消息将消息的值存储在 clientMsg 变量中。然后我尝试使用System.out.println()显示clientMsg的值,它的工作原理!但是当我访问MainActivity中的变量时,它的值变为null。有什么理由为什么?

7 个答案:

答案 0 :(得分:4)

无论您如何访问clientMsg,它都没有设置任何值。

所以你总是得到null

如果您希望主方法自动运行,则不会发生。你可以手动调用它。或者使用静态块进行初始化。

编辑:

您似乎在两个独立的JVM中运行它们。静态类是每个JVM一个。因此,当您单独运行它们时,另一个的更改将无法显示...

答案 1 :(得分:1)

只有当您执行“#”时,才会自动调用类中的静态main()方法。一个班级 -

    使用命令java package.name.Server 从控制台
  1. 来自Eclipse之类的IDE,将其作为Java应用程序'
  2. 运行
  3. 来自一个构建工具,它启动一个基本上完成上面第1点所写内容的过程。
  4. 如果您在Android应用程序中使用Server,则这些都不是真的。因此,如果您希望执行该方法,则需要自己调用它,比如在Activity的开头调用它。

    但是,签名public static void main()通常只是在将类作为Java应用程序运行时默认调用,所以正如Homam所提到的,您应该将代码移动到get方法以进行延迟初始化。或者,至少将main方法重命名为init(),并以其他方式自己处理类/变量的初始化。

    编辑(根据OP提供的反馈):

    您需要记住的是,这些规则仅适用于两个类在同一个虚拟机中运行的情况。如果在Eclipse中执行Server类,它将在Eclipse使用/分叉的JVM内运行。 Android模拟器内部发生的事情发生在Android附带的Dalvik VM中。就这两种环境而言,它与在两台完全不同的机器上运行它们没有什么不同。它们是两个不同的ClassLoader,两个不同的内存空间,在这种情况下,是两种不同的虚拟机技术。

答案 2 :(得分:0)

永远不会调用静态变量赋值的主函数。与普通的Java应用程序不同,Android不会为你调用main函数。 所以它总是为空。

答案 3 :(得分:0)

您的Server.main方法是否曾被调用过?

无论如何,Android有时会杀死你的进程并为你启动它,试图将它恢复到最后状态。如果你不仔细聆听这些事件,你可能会错过这个。在这些重新启动之间,静态变量将重置为其默认值。

不幸的是,我找不到一个描述应用程序生命周期的体面文档,只是一个描述活动生命周期的文档。我不想变得粗鲁,所以让我们说Android通常会使用吸力将东西从一个地方移动到另一个地方。

答案 4 :(得分:0)

main function的代码添加到getClientMsg function并删除main function,此处不需要它。

答案 5 :(得分:0)

试试这样:

public class Server {

    private static String clientMsg;

    public static String getClientMsg() {
        while (true) {
            try {
                clientSocket = serverSocket.accept();

                // READ THE MESSAGE SENT BY CLIENT
                dataInputStream = new DataInputStream(
                        clientSocket.getInputStream());

                // Here is where I assigned the static variable clientMsg
                clientMsg = dataInputStream.readUTF();

                dataOutputStream = new DataOutputStream(
                        clientSocket.getOutputStream());
                dataOutputStream.writeUTF("Message Received!");

            } catch (IOException e) {
                e.printStackTrace();
            }

            /* Rest of the code here */
        }

        return clientMsg;
    }

}

答案 6 :(得分:0)

问题在于:

最初clientMsg的值为null。现在,您通过在main函数中编写的代码为clientMsg赋值,并且永远不会调用main函数。

因此clientMsg的值保持为空。

解决方案:将整个代码放在getClientMsg()方法中。