java scala migration scala-java-interop

Migración de Java a Scala



migration scala-java-interop (5)

¿Cuáles son los puntos más importantes a tener en cuenta, y las soluciones alternativas, al migrar gradualmente una base de código Java existente a Scala? Con una fase intermedia (potencialmente muy larga) donde ambos idiomas están en uso.

El tipo de cosas que estoy pensando son:

  • diferentes jerarquías de colección
  • Java construye que Scala no puede manejar bien
  • Construcciones de Scala que no son prácticas para usar en Java
  • construir herramientas
  • orden de compilación
  • Soporte de inmutabilidad en marcos.
  • etc.

Agregaré a lo que otros han dicho ya que son correctos y significativos. Más que solo el código, tendrá que traer sus pruebas de unidad. Esto no suena difícil hasta que empiezas a cambiar la mutabilidad y las construcciones de subprocesos mientras intentas que todo funcione de la misma manera que antes. Durante la transición, es muy importante tener en cuenta todos los casos de borde mientras se descubren casos de borde adicionales que puede presentar durante la migración.

Si lleva sus pruebas de unidad a un buen marco de prueba de Scala como ScalaTest con una traducción directa, puede encontrar que lo que está probando no es lo que estaba probando antes. Al realizar su migración, es importante que mantenga la intención del código junto con las pruebas en lugar de permitir la fragmentación del pensamiento.


Inicialmente (es decir, la primera fase de la migración), diría que no desea exportar una API (interfaz / método público, etc.) con una estructura de scala de difícil uso desde Java.

En la práctica, limitaría esto a exportar cualquier cosa que sea específica de Scala (nuevamente, estoy hablando de la primera fase de migración aquí):

  • Clases de la biblioteca de Scala (tipos de funciones, colecciones, etc.)
  • firmas de tipo genérico de clase superior
  • implícitas

Entonces, ¿qué deja eso? Bueno, las partes internas de las clases (métodos privados, campos, etc.) se pueden convertir para usar construcciones de scala y clases de biblioteca.

Si tiene alguna API (especialmente las API orientadas al cliente que pretende migrar), las diseñaría de nuevo desde cero en Scala; inicialmente utilizando un back-end de Java. Luego me comería lentamente el código intermedio.

De los puntos que ha resaltado, estoy de acuerdo en que el paradigma inmutable de Scala y el paradigma mutable de Java no se mezclan bien. Los otros puntos que he encontrado menos problemáticos.

Otro punto principal de la discrepancia de paradigmas es cómo convertir cualquier código concurrente que tenga (es decir, el que hace uso de java.util.concurrent ). Por supuesto, esto se puede convertir tal como está, pero la pregunta es si se debe reemplazar el modelo de concurrencia basado en el bloqueo con uno basado en actors o STM . En cualquier caso, es probable que esto también sea un rediseño completo, en lugar de una conversión en .


Scala no le gusta

  • clases internas de Java
  • Métodos y variables estáticas (especialmente en súper clases)
  • tipos crudos

Java no le gusta:

  • Rasgos de objetos de Scala
  • cierres
  • actores (excepto Scarlett Johansson y Akka Actors, ya que tienen una API de Java)
  • implícitos, especialmente Manifiestos
  • construcciones de tipo avanzado (tipos ordenados superiores, tipos estructurales, vars de tipo abstracto)

Un truco que me gusta usar, @BeanProperty un objeto usando las propiedades idiomáticas de Scala (vals y vars), luego @BeanProperty anotación @BeanProperty para exponerlas luego como propiedades JavaBean. De esa manera, cada idioma puede utilizar los idiomas nativos.

La anotación @BeanInfo también se puede usar en un nivel de clase para un propósito similar, pero debe tener cuidado aquí: al usar @BeanInfo, cualquier método que defina de forma personalizada como setXXX o getXXX no se expondrá a través de la introspección del bean. . Esto es importante, ya que tiene que escribir manualmente getters / setters para los tipos de colección si también quiere manejar la traducción entre, por ejemplo, Scala Lists y Java Lists.