在用java写代码时, 主函数前为什么要加static

解决方案 »

  1.   

    而且估计后面会有人说main方法是非对象的,是属于类的。别扯了, 
      

  2.   

    说是非对象也说的过去啊。
    而且从main的作用来看,和static的定义也相符。
    不过说到底,也只是因为是这样规定的。
      

  3.   

    这个,至少要从Main方法的起源说起,还要考虑面向对象的对象职责,参考C#的设计,等等,你才能知道我说的。
      

  4.   

    因为static方法不需要创建对象 可以直接访问 这样main方法就不需要做特殊处理(愚见)
      

  5.   

    static方法在静态数据区中,这样就可以直接调用不需要每次调用都要重新生存。
      

  6.   

    我的理解跟cyberpeng差不多,也没看出跟healer_kx的说法有什么冲突的。不过main方法的确比较特殊一点,比较它的public。对于一般的类来说,它的属性和方法的可访问性不能超过它自己的可访问性,也就是说一个friendly的类,它的方法和属性不能是public的。但对于main方法来说,就算它所在的类是friendly的,它也必须定义为public的。
      

  7.   

    静态函数在调用时不用实例化,ninesea说的很有道理
      

  8.   

    这个就是理解层次的问题。
    但是我怎么都想不到SUN搞出来到Java的main函数是为了啥实例化问题的。
      

  9.   

    静态,以上来就装入内存 main函数其实也是所在类的一个方法,就比如一个类是test,那么该类的main其实就是test.main(String[] args),众所周知如果一个方法不是静态的,则要先实例化该类,比如要这样 test t=new test(); 
    然后才能调用 test.main(); 
    而这对于运行一个程序的主函数来说是不现实的,所以比如把main函数定义为static,使test.main()可以直接被调用。 因为main就是这个类的主函数,入口,如果每次进这个入口的时候再去实例话然后再去调用这个入口方法,就很罗嗦 石头,来,赚你点分~
     
      

  10.   

       我的理解也差不多,大概和main方法最先执行有关系吧.....
      用static修饰不用包涵main方法就能打印hello world,估计和这个有关....
       理解的较浅......不要耻笑...
      

  11.   

    按类的加载顺序,是先执行 static块 、静态变量 、 static 函数
      

  12.   

    main函数不加static也行
    不过与普通方法没什么两样
    好好看看static那一节
    很有好处,有些比较难懂
      

  13.   

    我们考虑这样一个问题,我们在写一个类,随便一个类,然后我们需要一个功能,比如说是“从某个字符串中得到ASCII最大的字符的位置”(我承认这个例子很烂,但是你也可以想象为max(Object, Object),或者是其他的例子)。class A
    {
        int indexOf(String);
    }
    语法凑合看,我只把最关键的语法写出来。
    后来我们发现,class B也可能需要这个功能,OK,代码重用嘛,但是我们用这个功能的时候,也不能new A()啊,浪费嘛。
    于是,改写成下面的模样,
    class A
    {
        static int indexOf(String);
    }
    OK, 于是,到这里,你们认为这不是和main函数是static的道理是一样的嘛?No,我还有很多废话要说。因为indexOf方法的功能,和A,和B的功能是正交的,知道什么是正交(不知道的baidu)吧?于是根据单一职责原则的理论,
    有点良知和进取心的人都会把该方法移动到一个Utilities的类中,对吧?
    到这里,你应该明白点什么了吧?我们再继续说c/c++的main函数。
    一个真正的程序员,至少应该知道一个C程序就一个main函数,作为程序的起始,不过这都是教大学生的教材说的。
    如果你会写CRT的话,那么你可以让一个C程序从任何一个函数运行起来,main函数不过是在crt main上的一个对于普通开发者的开始。
    可是你知道宇宙大爆炸之前就真的没有历史了嘛?
    main,并非是一个真正特殊的函数,它都可以参与递归。在Java里面,main函数是起始嘛?也许对于Java语言来说是,但是对于Java平台来说,不是。在main之前已经有很多的C函数和Java方法被调用了。为什么C#只有一个Main方法?
    C#和Java就像是一个弟弟,一个哥哥一样,但是Java的启动方式是java StartupClassName
    于是,你可以在许多类中加入main函数,但是.Net要生成.exe文件,所以设计上倾向于只有一个Main函数,以通知.Net框架程序的入口地址是什么。
    但是,.Net框架下的语言,并非所有都需要一个main的,这就说明了,main,没有什么了不起。
    但是Java比较可以通过双击.jar文件,和一个.manifest文件来模拟出这种只有一个Main方法的软件行为。我可以让一个main方法作为一个对象成员方法嘛?
    可以,既然main函数不再特殊了。我就写过CRT程序,听起来很神奇,其实很简单。因为main并不特殊。
    但是!! 这样做没有意义。前面有人说起什么什么静态,内存,还有什么时候加载的问题。
    先从汇编说起,C++里面调用一个static函数,和一个成员函数的差别在于哪里呢?
    以x86下,VC产生的汇编为例:
    调用一个static函数,
    汇编大致做了两个事情,
    push arg1
    push arg2
    ... ...
    call function调用一个非static的函数,汇编看起来是这个样子的。
    move ecx, object
    push arg1
    push arg2
    ... ...
    call function当然了,这个是甘草的汇编伪码,如果我们看byteCode
    那么差别在于两处。
    第一个是对象的实例。会多出来一个aload的指令,。
    第二个是invokestatic和invokevirtual的差别。但是我以为,都是invoke而已。做的事情大同小异的。无非是告诉JVM,我们这里有一个对象。我们从宏观上来说,这样会更好的理解。
    Ruby,语法中有实例方法(非static的)和类方法(就是static的方法)
    这两种方法有本质区别嘛? 从面向对象的角度来说有,但是从我们进来研究main的角度来说,调用这二者差别不大。
    Ruby中的关键字self 就是我们熟习的this。当Ruby调用类方法的时候,也会传递给方法一个self,这个时候self是一个调用者,或者称为接收者(Receiver).比如说调用一个全局的函数,
    就把全局这个Context传递给这个方法。
    而调用成员函数的时候,这个时候,self就等同于java的this和C++的this指针。
    哪个函数不是一开始就加载了?哪个函数不是有固定地址的?
    看过《C++对象模型》,就知道了,static方法和非static方法在内存中都是只有一份的,差别只在于传递给它的this是什么(对于许多语言来说,问题变为传递还是不传递),这份内存放的就是Code,就是C语言经常说的代码区,里面是指令。NOW!
    A.java, B.java, 现在如果A类持有main方法,B不持有,那么我们根据面向对象的理论和单一职责原则,和其他一些习惯。
    我们把A中的main,剪切到B中,当然了,不考虑import的问题,你看到了什么?
    我靠,还能移动啊? 和A类没有关系啊? 那放在A类里面干鸟啊?所以,我很明确的告诉你,main是public static的,只是语法规定,是迁就Java的语法。
    当然了,也不是一点关系都没有,在今天的Java里面,A里面的main通常表示A类的测试代码起始,B里面的main,也是这个意思。
    但是卢梭批评亚里士多德说:“是的,人生来就是不平等的。但是,他错了,他的错误就在于他把结果当原因!”
      

  14.   

    就像任何事物的循环传递总要有个起点和基地。
    static main 就是那个基地。
      

  15.   

    也许我比较愚笨
    我只觉得main跟一个普通的静态方法没什么区别,就是放进constant_pool之后就可以直接拿来用而已
    只是JAVA特地留出了这个入口标记而已,我也没办法的
      

  16.   

    如果是因为static的话,那我去试试在类里定义个static方法调用没有static的main方法
      

  17.   

    最近整理书籍的时候 翻到以前大学的时候C语言的书 
    就是老谭那本 然后就顺手拿起来翻了翻 
    以前我一直觉得老谭这本书不错 基本上是所有科班程序员的启蒙之书
    可这次翻了以后 立马觉得恶心 这tmd什么垃圾书 废话连篇 看了几页就丢一边了 真想不通 这破书我以前是怎么看下去的healer_kx 甘草    你的废话也相当的多  你说这么多也未必能让人明白
      

  18.   

    卢梭批评亚里士多德说:“是的,人生来就是不平等的。但是,他错了,他的错误就在于他把结果当原因!” 这句不错~~~~~~~~~~~~~~~~~~~~~~~~
    to  teng2048 class A
    {
    static
    {
    main();
    }

    public void main()
    {

    }
    }
      

  19.   

    能达到同样的效果
    但是会Exception in thread "main" java.lang.NoSuchMethodError: main
      

  20.   

    CSDN不能重新编辑 确实垃圾的很  垃圾的很啊~~~to     teng2048   
    class   A 

    static 

    new A().main(); 
    } public   void   main() 
    { } 
    }
      

  21.   

    main在程序执行时要自动分配内存
    所以要加static
      

  22.   

    我说那么多不是为了让人明白的,想让人明白,我就只写java代码了。
      

  23.   

    假设没有static关键字,那意味着需要用生成一个实例后才可以调用这个main方法,而main方法是程序入口点,你没有进入main方法,自然无法生成一个实例,既然没有实例,那就无法调用main函数,岂不矛盾?所以main函数被设置为static.
      

  24.   

    甘草的讲解对于main函数的具体实现十分透彻,但我觉得“是迁就Java的语法”这句话还是有问题。既然Java作为程序入口的main函数已经这么特殊了,那么为什么不再让它更特殊一点,直接给它一个关键字好了。所以我觉得之所以会有static关键字,更重要的是Java为了表明main方法与对像实例之间的关系。至于具体底层怎么实现,则是以这个思想为指导的,并且也只是给出了一种可能的方式而已。C++不就是通过C来实现了面向对像思想吗?但它们两者对于程序开发来说,关键的差别我想也不是,至少不全是所生的汇编代码不同吧。
      

  25.   

    你看楼上的觉悟,这就对了,规定。[使劲bold]规定![/使劲bold]
      

  26.   

    没有人反对说,这么定义不是因为规定。
    是的,如果不是语法的强制规定,main()也就是一个普通函数。
    但是为什么不强制规定private void main(String[] args);为程序入口?
    从语义来说这个入口函数不是只给所在类自己用的,也不仅仅是给同一个包内的类用的,也不是只给它的子类用的,所以声明为public;因为这个方法的作用与类的实例联系不大,声明为static,所以就声明为static。这都说不过去?
      

  27.   

    main 函数是程序的入口,将其设置成static是为了当main函数所在类在加载完毕后能直接调用执行main函数,而不需要实例化该类
      

  28.   

    public class Test
    {
      static
     {
        System.out.println("NOMain");
        System.exit(0);
     }
    }
    看看````
      

  29.   

    说通俗点,如果main方法不是static,程序还没运行,你上哪去new一个包含main方法的类来掉用main呢?
      

  30.   

    如果只是一个普通的类的话,是先要创建对象才能调用这个类中的方法.但是JAVA的程序中一般只有一个类,而不创建他的对象,这样的话,JAVA程序是不能执行的,因此就要在定义他的主函数是用一个STATIC,因为加了这个东西,就相当于程序在编译时就已经创建了一个对象了,也就可以接下去执行了
      

  31.   

    如果不是静态的就得new一个对象,但无static的main 有无法创建对象!main()是编译器启动调用的!
      

  32.   

    想一下 一般你都用怎么用这个main函数 你就会发现为什么会这样了
      

  33.   

    static修饰的方法是类方法,不需要对象,就能搞调用!在程序的入口处执行时,还没有产生任何对象!所以如果不是static的,就根本不能调用,程序还会执行吗?
      

  34.   

    如果 main 不加个 static 的话,就是表示,应该先 XXX a = new XXX() 再调用 a.main, 又请问,谁来 new XXX() 呢?需要使用 static 因为对象需要先在内存中建立状态才能被使用(我们也可以把一个非 static 的方法理解成相对于一个对象的内存位置需要一个偏移量才能访问,就好像 C++ 动态绑定一样),而当刚开始执行时,内存中还没有这个能当引路人的对象,我们无法做到,就出现了是鸡生蛋还是蛋生鸡一样的死循环。而 static 方法是一个不和对象状态绑定的方法,有时我们也说是无状态的方法,它不需要一个对象事先存在就可以调用它的方法。说回来,还是 static 这个概念的问题。
      

  35.   

    main方法是程序的切入点,不用任何对象,由jvm去执行这个方法
      

  36.   

    纠正:
    需要使用非 static 方法的话那么这个对象需要先在内存中建立状态才可以调用。CSDN 不能编辑回复,鄙视。
      

  37.   

    同意main()不属于任何一个类(不信你用类名或实例的引用点取试试),它是java提供的应用程序启动点,因为不属于任务一个类,当然要public static.
      

  38.   

    顶           static实现静态接口                    
      

  39.   

    以前只知道一个程序只能有一个main函数学习!!!
      

  40.   

    受教了
    原来的CSDN真好多好人呐 = =  
      

  41.   

    这样定义和JVM的运行有关系。
    当一个类中有main()方法,执行命令“java 类名”则会启动虚拟机执行该类中的main方法。
    由于JVM在运行这个Java应用程序的时候,首先会调用main方法,调用时不实例化这个类的对象,而是通过类名直接调用。
      

  42.   

    因为main方法不对任何对象进行操作,静态的main方法将执行并创建程序所需要的对象。
      

  43.   

    加上static后jvm调用main函数就不用新建一个对象
      

  44.   

    甘草很犀利,解释的真精彩,确实就是个规定
    但是一直发现一个问题是接触过的几乎所有oop语言,一个应用的入口通常都是一个过程,而不是一个对象,就算不是一个一般意义上的过程,也是一个异于对象的东西,有的叫application有的叫programme,但是其我的理解还是一个过程,至于之中的道理我的水平解释不了
    虽然基础的java的启动函数main被封装在了类中,但冥冥中觉得,把这个main写成static还是为了脱离此函数与类的关联性,这样承载main的类可以只是app中一个普通的类,只是在config中指明入口在他那,但其实并不属于他,如果去掉static,那我们就要说,启动的通过一个对象,那这个对象身后的类必定在这个应用中的地位和其他的类不一样了,至于真的有什么不好,就像之前说的,大多oop语言启动入口都是一个过程,我不知道为什么,可能就不太oop了??当然这个规定是为了迁就java之前已经制定的理论体系,可能宏观上看他并没有什么必须存在的理由,但可能对于java本身,他能使java的理念自圆其说
      

  45.   

    ...看了半天 没啥感觉
      就是觉得sun为了自圆其说? 既然定义了一套体系,不过不照自己的规矩就打自己的嘴巴了?
     纯粹为了灌水..
      

  46.   

    书上抄的写下来  跟很多人的说法一样  毕竟有因就有果  对于任何有严谨逻辑的人来说 一句话说是规定  实在让我这小菜鸟难以接受 所以查书抄了一段话
    ----->>
       main()是java应用程序的主入口方法,在该方法前面添加static修饰表示该方法是与类相关的,java解析器运行时将会寻找该方法。之所以将main()方法定义为类相关,愿意是在解析器调用该方法时,还没来得及创建当前类的对象,因此不能定义成与对象相关的方法。
      

  47.   

    觉得还是因为static是在静态代码块里,java虚拟机能最先调用并且不需要实例化
      

  48.   

    在main前面加上static表示main方法是静态的方法,那么当执行程序的时候,编译器首先会找到main方法所在的类,然后进行加载,那么什么加载到内存中呢??会把static关键字修饰的变量,方法放在加载进去内存中。同时用static 修饰的变量或方法都是属于某个类的不是某个对象的。也就是说即使没有定义任何对象,那么static修饰的变量或方法都会被加载到内存中,另开辟一片空间供类的所有对象共享!!!!
      

  49.   

    我敢保证·LZ在发帖的时候不会想到这么一个问题会引发这么深邃的思考··所以··我也只能以我个人的浅层次的理解来回答一下楼主··因为加了static关键字··该方法就能直接被访问··能在运行时直接被访问的方法也只能是静态方法··所以··main()函数在程序运行的时候直接被访问··也就是第一个访问··所以可以作为主函数·又称函数的入口··其他的方法如果定义成静态·那也是可以直接在main()方法里直接调用的··静态的意思就是:可以直接被调用··嘿嘿··轻砸··
      

  50.   

    标记为 static 的方法, 虚拟机不需要创建对象, 就可以调用main 方法是程序的入口, 尚未进入程序, 不能创建对象, 所以使用 static 正好, 不创建对象就能启动程序!如果你设计虚拟机, 你也可以叫虚拟机没有进入程序的时候也能创建对象(创建哪个对象,怎么创建对象你自己想办法搞定),但是总得选一种方式, Sun的设计师选择了前者仅此而已!
      

  51.   

    Static 可标志静态类,与静态方法,也可标志静态域,编译器在载入类时会先载入Static标志的区
      

  52.   

    我认为有两个原因(目前为止发现):第一,static修饰部分的内容存在静态区域内,当类加载的时候,先执行static部分,而main函数一般都是作为程序的入口函数,所以用static修饰时可以保证程序从该主类下的main函数首先执行;第二,如果不加static的话,那在main函数中就不能直接调用静态变量,静态修饰的函数了,而API里面有很多方法是用静态修饰的,所以,不加static修饰,有时候使用那些函数的次数多了就会显得不方便
      

  53.   

    以前看过一本书, 叫jvm xxx里面有说到。
      

  54.   

    Java中的static方法,java虚拟机运行java程序是从main函数开始的,设置static的目的是告诉虚拟机不需要生成类实例就可以直接使用类调用main()方法,void的目的是不要返回参数,至于String[]args是不成文的写法
      

  55.   

    本人用反证法证明一下:假如没有static的话,我们都知道main函数是第一个被执行的函数,但是在此之前不可能生成实例对象(因为没有执行任何代码),没有实例对象的话就不能用 “对象.main()”的方式来调用。因此,只能在main函数前面加上 static 用“类.main()”的方式来调用。
      

  56.   

    其实static没写,编译也不会出错的,但是运行时会出错。这个你懂得。