首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 在用java写代码时, 主函数前为什么要加static
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:18:20 楼主
      在用java写代码时, 主函数前为什么要加static
    20  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:20:191楼 得分:0
    因为语法这么规定的,其他的理由都是反证的。。。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:22:382楼 得分:0
    而且估计后面会有人说main方法是非对象的,是属于类的。别扯了,。。。 。。。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:28:033楼 得分:0
    说是非对象也说的过去啊。
    而且从main的作用来看,和static的定义也相符。
    不过说到底,也只是因为是这样规定的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:32:154楼 得分:0
    你看,我猜得还是很准确的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:37:225楼 得分:0
    ……

    难道说不过去?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 11:45:406楼 得分:0
    静态方法在内存中的位置是固定的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 12:33:117楼 得分:0
    这个,至少要从Main方法的起源说起,还要考虑面向对象的对象职责,参考C#的设计,等等,你才能知道我说的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ninesea
    • 等级:
    发表于:2008-02-28 12:40:558楼 得分:0
    因为static方法不需要创建对象 可以直接访问 这样main方法就不需要做特殊处理(愚见)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 12:45:309楼 得分:0
    学习
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 13:42:4410楼 得分:0
    static方法在静态数据区中,这样就可以直接调用不需要每次调用都要重新生存。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 14:02:5211楼 得分:0
    我的理解跟cyberpeng差不多,也没看出跟healer_kx的说法有什么冲突的。

    不过main方法的确比较特殊一点,比较它的public。对于一般的类来说,它的属性和方法的可访问性不能超过它自己的可访问性,也就是说一个friendly的类,它的方法和属性不能是public的。但对于main方法来说,就算它所在的类是friendly的,它也必须定义为public的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 14:47:1912楼 得分:0
    据说和函数入口,堆栈什么的有关系,不是很清楚
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:09:0913楼 得分:0
    静态函数在调用时不用实例化,ninesea说的很有道理
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:22:4214楼 得分:0
    这个就是理解层次的问题。
    但是我怎么都想不到SUN搞出来到Java的main函数是为了啥实例化问题的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:37:3615楼 得分:0
    静态,以上来就装入内存

    main函数其实也是所在类的一个方法,就比如一个类是test,那么该类的main其实就是test.main(String[] args),众所周知如果一个方法不是静态的,则要先实例化该类,比如要这样 test t=new test();
    然后才能调用 test.main();
    而这对于运行一个程序的主函数来说是不现实的,所以比如把main函数定义为static,使test.main()可以直接被调用。

    因为main就是这个类的主函数,入口,如果每次进这个入口的时候再去实例话然后再去调用这个入口方法,就很罗嗦

    石头,来,赚你点分~

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:43:1416楼 得分:0
    楼上的解释得很清楚!顶个!
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:51:4817楼 得分:0
      我的理解也差不多,大概和main方法最先执行有关系吧.....
      用static修饰不用包涵main方法就能打印hello world,估计和这个有关....


      理解的较浅......不要耻笑...
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:57:1318楼 得分:0
    按15楼的这样理解感觉比较好理解一些。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 15:57:5919楼 得分:0
    按类的加载顺序,是先执行 static块 、静态变量 、 static 函数
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 16:05:2520楼 得分:0
    我是个习惯吧.. 呵呵..  没有太去注意为什么一定要加
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 16:12:4021楼 得分:0
    main函数不加static也行
    不过与普通方法没什么两样
    好好看看static那一节
    很有好处,有些比较难懂
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 16:40:0722楼 得分:0
    静态方法~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 16:56:5623楼 得分:0
    我们考虑这样一个问题,我们在写一个类,随便一个类,然后我们需要一个功能,比如说是“从某个字符串中得到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,也是这个意思。
    但是卢梭批评亚里士多德说:“是的,人生来就是不平等的。但是,他错了,他的错误就在于他把结果当原因!”


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ninesea
    • 等级:
    发表于:2008-02-28 17:15:4624楼 得分:0
    哈 楼上的精彩
    不过还有一句 叫做 因果循环 哈哈哈
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • VBSpine
    • 等级:
    发表于:2008-02-28 18:50:1225楼 得分:0
    就像任何事物的循环传递总要有个起点和基地。
    static main 就是那个基地。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 18:54:0126楼 得分:0
    这个问题比较深遂
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 19:13:5527楼 得分:0
    拜一下甘草
    真能忽悠~
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-28 19:18:2828楼 得分:0
    你还是拜赵本山去吧,那是我师父.
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zapdos
    • 等级:
    发表于:2008-02-28 19:53:3229楼 得分:0
    也许我比较愚笨
    我只觉得main跟一个普通的静态方法没什么区别,就是放进constant_pool之后就可以直接拿来用而已
    只是JAVA特地留出了这个入口标记而已,我也没办法的
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-29 08:26:1730楼 得分:0
    平时还真没有注意,只是在当中是这么规定的,具体怎么个原理还真没有去认真探讨过呢。呵呵
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-29 09:15:2531楼 得分:0
    如果是因为static的话,那我去试试在类里定义个static方法调用没有static的main方法
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • insiku
    • 等级:
    发表于:2008-02-29 09:26:1532楼 得分:0
    最近整理书籍的时候 翻到以前大学的时候C语言的书
    就是老谭那本 然后就顺手拿起来翻了翻
    以前我一直觉得老谭这本书不错 基本上是所有科班程序员的启蒙之书
    可这次翻了以后 立马觉得恶心 这tmd什么垃圾书 废话连篇 看了几页就丢一边了 真想不通 这破书我以前是怎么看下去的

    healer_kx 甘草    你的废话也相当的多  你说这么多也未必能让人明白


    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    发表于:2008-02-29 09:28:0633楼 得分:0
    - -!
    写不出来,不道咋写.哈哈
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • insiku
    • 等级:
    发表于:2008-02-29 09:32:2434楼 得分:0
    卢梭批评亚里士多德说:“是的,人生来就是不平等的。但是,他错了,他的错误就在于他把结果当原因!”

    这句不错~~~~~~~~~~~~~~~~~~~~~~~~


    to  teng2048

    class A
    {
    static
    {
    main();
    }

    public void main()
    {

    }
    }
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • insiku
    • 等级:
    发表于:2008-02-29 09:33:1235楼 得分:0
    能达到同样的效果
    但是会Exception in thread "main" java.lang.NoSuchMethodError: main
    修改 删除 举报