Как Вы называете одноэлементный метод Scala от Java?

Я пытаюсь ввести некоторый код Scala в свое существующее приложение Java. (Так, быть сказанным, я хочу еще некоторую забаву).

Я создаю одноэлементный материал в Scala

ScalaPower.scala

    package org.fun
    class ScalaPower
    object ScalaPower{
      def showMyPower(time:Int) = {
        (0 to time-1).mkString(", ")
      }
    }

Теперь, в OldJava.java

class OldJava {
  public void demo(){
    System.out.println(?)
  }
}

Что я должен заполнить ? так, чтобы Java назвал showMyPower метод? Я попробовал обоих org.fun.ScalaPower.showMyPower(10) и org.fun.ScalaPower.getInstance().showMyPower(10) но ни один не работает.

(Декомпилируйтесь, файл класса с помощью Вруба показывают мне только код ерунды.)

Редактирование я удаляю class ScalaPower объявление и scala производят статический метод как ожидалось. (звоните в org.fun.ScalaPower.showMyPower(10) просто работы).

Удивление, если это - ошибка в scala компиляторе или нет

22
задан oluies 5 October 2010 в 13:02
поделиться

5 ответов

Я думаю, что это косвенно охватывает это:

Companion Objects and Java Static Методы

Есть еще одна вещь, которую нужно знать о объектах-компаньонах. Всякий раз, когда вы определяете главный метод для использования в качестве точки входа в приложение, Scala требует, чтобы вы поместили его в объект. Однако на момент написания этой статьи главные методы не могут быть определены в объекте-компаньоне. Из-за деталей реализации в сгенерированном коде, JVM не сможет найти главный метод. Эта проблема может быть решена в одном из будущих выпусков. На данный момент, вы должны определить любой главный метод в синглтонном объекте (т.е. "некомпаньонном" объекте) [ScalaTips]. Рассмотрим следующий пример простого класса Person и объекта-компаньона объект, который пытается определить main.

Как здесь: http://programming-scala.labs.oreilly.com/ch06.html

Короче говоря, поскольку ваш объект является объектом-компаньоном (имеет класс-компаньон), вы не можете вызвать его, как вы ожидаете. Как вы обнаружили, если вы избавитесь от класса, он будет работать.

9
ответ дан 29 November 2019 в 04:46
поделиться

Какие ошибки вы получали? Используя ваш образец Scala и следующий класс Java:

cat test.java :


import org.fun.*;

public class test {
    public static void main(String args[]) {
       System.out.println("show my power: " + ScalaPower.showMyPower(3));       
    }
}

И запустите его следующим образом:

java -cp.: < path-to / scala / install- dir > / lib / scala-library.jar test

дает мой результат:

показать мою мощность: 0, 1, 2

10
ответ дан 29 November 2019 в 04:46
поделиться

Имейте в виду, что можно использовать стандартный инструмент javap чтобы увидеть, что производит компилятор Scala. Конечно, он не дает прямого ответа на ваш вопрос, но когда вам нужно просто напомнить о шаблонах генерации кода, этого достаточно.

3
ответ дан 29 November 2019 в 04:46
поделиться

Обычно лучше получить доступ к синглтону напрямую из его собственного класса.

В данном случае:

org.fun.ScalaPower$.MODULE$.showMyPower(10);

Не вдаваясь в подробности реализации, Scala различает пространства имен между Object и Class / Trait. Это означает, что они могут использовать одно и то же имя. Однако у объекта есть класс, и поэтому ему нужно искаженное имя на JVM. Текущие соглашения Scala заключаются в добавлении символа $ в конце имени модуля (для модулей верхнего уровня). Если объект определен в классе, я считаю, что соглашение - OuterClass $ ModuleName $. Для принудительного применения одноэлементного свойства модуля ScalaPower существует также статический член MODULE $ класса ModuleName $. Это инициализируется во время загрузки класса, гарантируя, что существует только один экземпляр. Побочным эффектом этого является то, что вы не должны выполнять какие-либо блокировки в конструкторе модуля.

В любом случае, Scala также имеет встроенный механизм статических перенаправителей «сделать вещи лучше для Java». Здесь он пишет статические методы класса ScalaPower, которые просто вызывают ScalaPower $ .MODULE $ .someMethod (). Если вы также определяете сопутствующий класс, число серверов пересылки, которые могут быть сгенерированы, ограничено, поскольку вам не разрешается иметь конфликты имен со статическими методами и методами уровня экземпляра на JVM. Я думаю, что в 2.8.0 это означает, что если у вас есть объект-компаньон, вы теряете свои статические пересылки.

В этом случае «наилучшей практикой» было бы всегда использовать ссылку ScalaPower $ .MODULE $ вместо статического сервера пересылки, поскольку этот сервер пересылки может исчезнуть с изменениями в классе ScalaPower.

РЕДАКТИРОВАТЬ: Опечатка

17
ответ дан 29 November 2019 в 04:46
поделиться

После выполнения

class ScalaPower 
object ScalaPower{
  def showMyPower(time:Int) = {
    (0 to time-1).mkString(", ")
  }
}

ScalaPower.showMyPower (10) работает должным образом.

1
ответ дан 29 November 2019 в 04:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: