多种主要功能


69

我对此有些陌生,请耐心等待。我目前正在学习C#和Java,它们的相似之处之一是主要功能需要封装在一个类中。例如

public class HelloWorld {
    public static void main(String[] args) {
        // Some Code
    }
}

现在我了解到主程序通常是运行程序时的“入口点”。因此,基本上,您的程序将在主要功能所在的地方开始执行。但是我相信在两种语言中,您都可以在多个类中具有多个主要功能。因此,当我编译具有多个主要功能的项目时,“入口点”在哪里?编译器如何知道从哪里开始?


14
每种语言的答案都不同。
Mark Byers 2012年

Answers:


57

在.NET中,您可以定义哪个类包含要在编译时使用的Main方法。

http://msdn.microsoft.com/en-us/library/x3eht538.aspx

在Java中,如果绑定到jar,则可以在jar的清单中定义入口点。

http://docs.oracle.com/javase/tutorial/deployment/jar/appman.html


9
我很惊讶这是投票最多的答案。至少对于Java而言,Code-Guru和@CosmicComputer的答案对大多数人而言似乎更为相关。我会说很少的开发人员,除了少数运送“可执行”罐子的人之外,都曾使用manifest方法。
乔治·霍金斯

3
@GeorgeHawkins在我看来,这是回答两种语言问题的唯一答案,尽管对于Java来说,这可能不是最佳答案。
2684年

58

在Java中,计算机在实际执行程序时而不是在编译时确定“入口点”。例如,从命令行

java MyClass

搜索main()MyClass。所有其他main()功能都将被忽略。

如果使用的是IDE,则可以设置哪个类包含main()要使用的功能。


3
在Java中,它搜索public static void main(String[] args)
路易吉·门多萨

7
@LuiggiMendoza是的,这是正确的。为简洁起见,我省略了main()的完整签名,因为OP已经证明他知道它是什么。
法学徒

5
或方法签名public static void main(String[])或者public static void main(String ...)非常精确的。
Maarten Bodewes 2012年

2
其他主要方法不会“被忽略”,只是不会自动执行。程序员可以编写明确调用类的main方法的代码。
Zeke Hansell

3
hoo!我的第一个银牌!感谢所有对此答案投票的人!
法学徒

17

在C#中,可以使用多种Main方法。

如果有多种Main方法,则编译器将不知道要使用哪个入口点,因此它将向您显示错误。

需要指定Main在编译时使用方法:您可以指定在Visual Studio开发环境中或通过csc编译器将哪个方法用作编译器选项。


1
我不了解C#,但是在Java中,这是不正确的。Java编译器不在乎将使用哪个入口点。它将全部编译。另一方面,必须告知运行时环境要执行哪个入口点。
法学徒

2
是的...但是这是参考C#而不是Java
Anirudha

3
@ Code-Guru:答案对于C#是正确的,因为程序集在编译时指定了一个入口点-您在执行时不必指定类名,而只需指定程序集名即可。
乔恩·斯基特

2
@JonSkeet原始答案未指定语言。感谢您的编辑,Anirudha。
法学徒

12

主类是特殊类,仅出于一个原因:运行Java虚拟机时,JVM调用该函数。从本质上讲,它与任何其他函数一样,实际上,您可以从另一个类调用一个类的主函数。

当您编译具有多个类的项目时,您告诉JVM使用要使用的主类来运行该类,如下所示:

java SomeClass

并假设SomeClass已编译并且相应的编译文件位于您的类路径中,它将运行SomeClass的main方法。(这是您必须在特定的OS上解决的问题,但我认为-cp选项指定类路径非常普遍)。所以这:

java -cp /home/MyName Someclass

将在目录/ home / MyName中运行SomeClass的主要功能


9

在C#中,您可以使用 /main:编译器选项。

考虑以下包含两个main()功能的代码:

namespace Application {
    class ClassOne {
        static void main () {
            // Code here
        }
    }

    class ClassTwo {
        static void main () {
            // Code here
        }
    }
}

ClassOne.main()用作入口点,在编译时应指定以下内容:

csc /main:Application.ClassOne hello.cs

7

正如其他人指出的那样,在Java中,您在运行java命令时定义包含主函数的类。

但是,您也可以构建一个可执行jar,可以使用来运行它java -jar my.jar。在这种情况下,您需要在jarMANIFEST.MF的文件夹META-INF中调用一个清单文件。在此文件中,您可以使用语句指定包含主要功能的类Main-Class: YourClass


7

对于多个主要功能,可以通过以下方式声明入口点:

在Visual Studio开发环境中设置此编译器选项

打开项目的“属性”页面。

单击应用程序属性页。

修改启动对象属性。

参考:http : //msdn.microsoft.com/zh-cn/library/x3eht538.aspx


您是否有想法在JetBrain Rider中做同样的事情?因为我试图查看项目应用程序的属性,找不到启动对象
VectorX

抱歉,我的机器上没有安装JetBrains。
NG。

要在Rider中更改启动对象,您必须编辑.csproj文件(也许使用F4,取决于键绑定)。
西罗·马特奥斯

4

main方法是静态的,这意味着它属于类而不是对象。因此,对象内部根本没有其他主要方法。它不会有其他main方法,因为main是静态的。因此,每堂课一次。

如果项目中有多个主方法,则在启动应用程序时将指定要启动的主方法


只是为了澄清起见,一类可以有多个主要方法。例如,您可以拥有public static void main()public static void main(String[])。在Java中,运行时环境将寻找要运行的后一个签名。
法学徒

2

实际上,在二进制文件中,例如Windows中的PE格式和Linux或任何其他系统中的ELF格式,二进制文件的标头将指定起始地址在哪里,并且只能有一个。

哪个应该是切入点?这取决于链接器。就像@SetFreeByTruth所说的那样,您可以使用命令行参数来指定它。许多链接器支持使用命令行参数指定入口点。例如,gnu的gld可以使用参数-e指定入口点。

我不知道Java的行为,因为它是由Java虚拟机加载的。


-1

在Visual Studio中,选择要作为入口点的项目,右键单击并设置为“启动项目”。


那将是“启动项目”,但这不是他们的意思。如果在一个项目/程序集中有多个潜在的入口点,则将打开项目属性,然后从应用程序窗格的“启动对象”下拉菜单中进行选择。
Cee McSharpface '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.