2014-05-01 123 views
23

我寫了一個Scala類,並在其中定義了main()方法。它編譯,但是當我跑它時,我得到了NoSuchMethodError:main。在所有的scala示例中,我已經看到,主要方法是在一個對象中定義的。在Java中我們定義了一個類中的主要方法。是否可以在Scala類中定義main()還是我們總是需要一個對象?Scala中的主要方法

+7

它只是一個對象。在Java中它真的是靜態方法main。但是在scala中沒有'靜態'方法。 –

+0

@EugeneZhulenev:這是一個答案... –

+0

對象是否也不需要擴展應用程序呢? – Totoro

回答

14

正如Eugene在評論中所說,Scala中沒有靜態方法。但是看這個:

$ cat Echo.scala 
object Echo { 
    def main(args:Array[String]):Unit = args foreach println 
} 

$ scalac Echo.scala 

$ javap Echo\$.class 
Compiled from "Echo.scala" 
public final class Echo$ { 
    public static final Echo$ MODULE$; 
    public static {}; 
    public void main(java.lang.String[]); 
} 

$ javap Echo.class 
Compiled from "Echo.scala" 
public final class Echo { 
    public static void main(java.lang.String[]); 
} 

注意,對於回聲類的類文件(不是echo $,對象)確實有一個公共靜態無效的主要方法。爲了與Java兼容,Scala爲對象中定義的方法生成靜態方法。

但是,我認爲在Scala程序中創建一個主要方法是不合時宜的。改用App特質;它的清潔:

object Echo extends App { 
    args foreach println 
} 
+0

不幸的是,使用'App'還有其他問題:http://stackoverflow.com/questions/29133161/scala-member-field-visibility-in-spark-jobs。但爲此,我同意應用程序在理論上更乾淨。 –

32

要回答你的問題,有以下一起來看看: 我做了一個階類,編譯和反編譯它,我得到了什麼有趣的。

​​

因此,這意味着,當階類轉換爲java類然後其又被轉換爲在java類main方法的類階的主要方法是不是靜態。 因此,我們將無法運行該程序,因爲JVM無法在程序中找到起點。

但是,如果相同的代碼使用「對象」關鍵字,然後做:

Compiling the following: 

object MyScalaClass{ 
def main(args: Array[String]): Unit = { 
    println("Hello from main of object") 
} 
} 

Decompiling the following: 
javap MyScalaClass$.class 

Compiled from "MyScalaClass.scala" 
public final class MyScalaClass$ { 
public static final MyScalaClass$ MODULE$; 
public static {}; 
public void main(java.lang.String[]); 
} 

Decompiling the following 
javap MyScalaClass.class 

Compiled from "MyScalaClass.scala" 
public final class MyScalaClass { 
    public static void main(java.lang.String[]); 
} 

所以在這裏我們得到了公共靜態無效的主要在MyScalaClass.class因此可以執行的主要方法直接由JVM在這裏。

我希望你能得到你的答案。

0

當我想在智能思想scala編輯器中測試我的代碼時,我只是在我的類下面創建一個伴侶對象,並在其中放置了一個主要方法。就這樣。看一個例子:

class Colon { 
    class Cow { 
     def^(moon:Moon): Unit ={ 
     println("Cow jumped over the moon") 
     } 
    } 
    class Moon{ 
     def ^:(cow:Cow) = println("This cow jumped over moon too") 
    } 
} 
object Colon{ 
    def main(args: Array[String]): Unit = { 
    val c:Colon = new Colon 
    val cow = new c.Cow 
    val moon = new c.Moon 
    cow^moon 
    cow ^: moon 
    moon.^:(cow) 
    } 
}