在应用程序中,有专门的静态区来存放静态的变量和方法,当你一个类初始化时,里面如果有静态变量或者方法,那么它先看静态区中有没有这个静态变量,如果有的话,直接使用这个变量,如果没有则在静态区中申请新的空间来存储变量,所以引用的时候,如果修改了一个类的静态变量,再次申请一个新的类实例时他的静态变量的值,和原有的实例的值是相同的。但是在applacation中,每个变量的生命周期不同,所以不是所有的静态变量都能像Web中那样,我觉得Web中就好像一个程序始终在运行着,所以创建的实例始终在内存中,和Scope相关,如果你要在Applacation中使用静态变量像在Web中一样,你要保证你的静态实例不被destroy。
这是我的理解。
你的例子改成这样就只打印一次了。
public class Hello 
{
private static String str;
public static void doTest()
{
if(str==null)
{
str = "Hello";
System.out.println("init str......" +str);
}

}
public static void main(String[] args){
Hello h1 = new Hello();
h1.doTest();
Hello h2 = new Hello();
h2.doTest();
}
}

解决方案 »

  1.   

    web容器中,确实是jvm从来没有关闭,所以静态变量一直存在,所以无论客户端运行多少次,始终是只创建一次静态对象,这种情况是所有线程共享一个静态区,而在application中是每个线程都有一个独自的静态区,所以才会出现每运行一次application都会创建一次静态对象。其实你上面写的那个程序,如果程序运行结束后再次运行的话,还是会打印出"init str......Hello"
    而我想要的结果是再次运行的话就不打印这个语句了,因为静态对象在上次运行的时候已经创建,所以if(str==null)不成立,不知道能不能实现。
      

  2.   

    程序启动时才会给它分配堆、栈、静态存储区这些内存空间,程序结束后再次运行,当然就是重新分配了。你重新启动web server,它也是要重新分配的。
      

  3.   

    照楼主的意思,只能把你想要一直保存在内存中的静态内容写在一个线程中,让其一直运行,当然如果destroy了这个线程,照样得重新初始化。
      

  4.   

    ,+***+,                                     
        ,*********,  ,               ,@@,             
       .****+++****,*:               ,WW.             
      ,***:.,,,.+****+               ,WW.             
      ***.,     ,:***+               ,WW.             
     .**:        ****+               ,WW.             
     +*+,       ,.+++. :@@*,     +@@:,WW.*@*.#@:      
     **:         ,,,,,WWWWWW:  ,WWWWWWWW.#WWWWWWW,+++,
    ,**:             @WW@*WW.  WWW**WWWW.#WWW#*WW* :: 
    ,**:             WWW*,.., #WW:,,.@WW.#WW+.,+WW,. .
     +*+,            .WWWW+,  WW+,   .WW.#W@.  .WW,+# 
     .**,            ,:WWWWW:,WW:    ,WW.#W@,  .WW,@@,
     ,***,       .,   ,.:#WWW.WW*,   .WW.#W#,  .WW.#+,
      .***,     +**,  +,,,WWW:+WW.   WWW.#W#,  .WW.  ,
      ,.*****+*****.  WWWWWWW.,WWWWWWWWW.#W#,  .WW,**,
       ,.********+., :WWWWWW+, .@WWWW@WW.#W#,  .WW,** 
         ,.+++++:,   ,.:++:.,   ,:++:.++..++,  ,++,,, 
           ,,,,,       ,,,,       ,,, ,,,,,,    ,,    
    用http://bbs.soulsky.net/pub/ascii/做的。
      

  5.   

    很简单,持久化,就可以模拟web容器的运行了哈
      

  6.   

    这个恐怕不行吧,servlet可以是因为其容器一直运行着,所以已经加载过的类不用再重新加载,如果你重新启动容器的话,所有静态数据也一样要重新生成。
    而一个应用程序和一个容器属于同一级,如果你想实现这个的话,那么也要有个应用程序来一直维持这些已经加载的类,不然它是不会孤立而且还一直存在的。
      

  7.   

    我觉得是这样:web app中jvm一直运行,所以只有一份的静态区一直存在而在app中,你在控制台中输入:java  Hello
    这时候jvm的一个实例也会启动,随后就是jvm读取byte code, 分配内存,开始执行,main方法结束后,jvm也就退出。 当你再次在控制台中输入:java  Hello
    就会重复上述过程,所以那句话还会打印