Scala-геттеры и сеттеры в классе Java

Я хотел бы создать класс Java, который следует соглашению о методах установки / получения Scala.

Я попробовал следующий простой класс, но он не работает:

public class JavaA {
private int a = 0;

public int a() {
    return a;
}

public void a_$eq(int a) {
    this.a = a;
}
}

Но когда я пытаюсь получить доступ к нему из Scala:

val x = new JavaA
x.a = 1

и я получаю "переназначение на val" сообщение об ошибке. Я пытался найти это, но все проблемы, которые я нашел, где-то наоборот, от скалы до Java.

Как правильно это сделать?

Спасибо!

 fikovnik06 июн. 2012 г., 00:21
Я много работаю с EMF (model2model, преобразование model2text), поэтому я подумал, что сделаю код немного более элегантным с помощью функции = значение вместо setFeatute (значение).

Ответы на вопрос(2)

ты не сможешь. В Scala метод доступа должен быть методом без списка параметров, напримерdef a = _a. Написание, напримерdef a() = _a в Scala вызовет ту же ошибку, и вы не сможете определить метод без списка параметров в Java. Вы можете обмануть компилятор Scala, сгенерировав собственныйScalaSignature, но это вряд ли стоит того ...

 Jean-Philippe Pellet05 июн. 2012 г., 16:28
@ TravisBrown Это так, потому что синтаксический сахар работает только при наличии такого средства доступа согласно спецификации языка.
 Travis Brown05 июн. 2012 г., 16:09
Проблема, однако, не в доступе.println(x.a) отлично работает (как иx.a_=(1)).
 Jean-Philippe Pellet05 июн. 2012 г., 17:56
@ kutschkem Ты не прав.def a() = … определяет пустой список параметров.
 kutschkem05 июн. 2012 г., 17:53
Пример с Scala не совсем верный, потому что, как я помню,def a() = _a не определяет пустой список параметров, но тот, который принимает Unit. Не уверен, что это только внутренняя часть или она сохраняется в процессе компиляции, но я думаю, это так.
 Travis Brown05 июн. 2012 г., 16:36
Ah! Вы правы. Как странно
Решение Вопроса

и это достаточно сложно, что ты, вероятно, не хочешь.

Что ты Не может do - это написать простой Java-класс, который магически интерпретируется как геттеры и сеттеры Scala. Причина в том, что Scala встраивает информацию в файл класса, который требуется для его методов получения и установки (например, есть ли блоки с нулевым параметром или один пустой блок параметра - различие, которое не сохраняется в JVM (или в Java)).

Что тыможе do - использовать Java для реализации определенного Scala-интерфейса (т. е. черта):

// GetSetA.scala
trait GetSetA { def a: Int; def a_=(a: Int): Unit }

// JavaUsesGSA.java
public class JavaUsesGSA implements GetSetA {
  private int a = 0;
  public int a() { return a; }
  public void a_$eq(int a) { this.a = a; }
}

Что ты Не может do, тем не менее, использует класс напрямую (опять же, потому что Java не добавляет соответствующую информацию аннотации для Scala):

scala> j.a = 5
<console>:8: error: reassignment to val
       j.a = 5

но так как это Делает успешно реализовать черту, вы можете использовать ее по своему усмотрению, когда она набрана как черта:

scala> (j: GetSetA).a = 5
(j: GetSetA).a: Int = 5

Так что это скорее смешанная сумка. Несовершенно, но в некоторых случаях может быть достаточно функциональным, чтобы помочь.

(Другая альтернатива, конечно, заключается в том, чтобы обеспечить неявное преобразование из класса Java в класс, который имеет метод получения / установки, который ссылается на реальные методы класса Java; это работает, даже если вы не можете получить наследование Java от Scala.)

(Изменить: Конечно, нет критической причины, по которой компилятордолже действовать так; Можно утверждать, что интерпретация определенных парами getter / setter Java, как если бы они были Scala (т. е. если файл классов явно не говорит, что это из Scala), является хорошим кандидатом для улучшения возможностей для улучшения совместимости Java.)

 fikovnik05 июн. 2012 г., 16:55
Спасибо за понимание! Я беспокоился, что это не сработает.
 Jean-Philippe Pellet05 июн. 2012 г., 17:18
Ницца; классный трюк с реализованной чертой!

Ваш ответ на вопрос