Основной метод в Scala
Я написал класс scala и определил в нем метод main(). Он скомпилирован, но когда я запустил его, у меня появился NoSuchMethodError: main. Во всех примерах scala, я видел, основной метод определен в объекте. В Java мы определяем основной метод в классе. Можно ли определить main() в классе scala или нам всегда нужен объект для этого?
спасибо
Ответы
Ответ 1
Чтобы ответить на ваш вопрос, посмотрите на следующее:
Я создал класс scala, скомпилировал и декомпилировал его, и то, что я получил, интересно.
class MyScalaClass{
def main(args: Array[String]): Unit = {
println("Hello from main of class")
}enter code here
}
Compiled from "MyScalaClass.scala"
public class MyScalaClass {
public void main(java.lang.String[]);
public MyScalaClass();
}
Таким образом, это означает, что когда класс scala преобразуется в класс java, тогда основной метод класса scala, который, в свою очередь, преобразуется в основной метод в классе java, не статический,
И, следовательно, мы не сможем запускать программу, потому что JVM не может найти начальную точку в программе.
Но если тот же код выполняется с помощью ключевого слова 'object', то:
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[]);
}
Итак, мы получили public static void main в MyScalaClass.class, поэтому основной метод может быть запущен непосредственно JVM здесь.
Надеюсь, вы получили свой ответ.
Ответ 2
Как сказал Юджин в комментарии, в 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 (не Echo $, объект) действительно имеет общедоступный статический метод void. Scala генерирует статические методы для методов, определенных в объектах для совместимости с Java.
Однако я считаю, что создание основного метода в программе Scala является анахронизмом. Вместо этого используйте свойство приложения; это чище:
object Echo extends App {
args foreach println
}
Ответ 3
Когда я хочу протестировать свой код в интеллектуальном представлении 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)
}
}