variable uso parametros modificadores modificador metodo clase acceso scala static-analysis case-class scala-wartremover

scala - parametros - uso del final en java



¿Debo usar el modificador final al declarar las clases de casos? (1)

De acuerdo con la herramienta de análisis estático scala-wartremover , tengo que poner "final" delante de cada caso de clases que creo: el mensaje de error dice "las clases de casos deben ser finales".

De acuerdo con scapegoat (otra herramienta de análisis estático para Scala), en cambio, no debería (mensaje de error: "Modificador final redundante en la clase de caso")

¿Quién tiene razón y por qué?


No es redundante en el sentido de que usarlo sí cambia las cosas. Como era de esperar, no puede extender una clase de caso final, pero puede extender una clase no final. ¿Por qué wartremover sugiere que las clases de casos deben ser finales? Bueno, porque ampliarlos no es realmente una muy buena idea. Considera esto:

scala> case class Foo(v:Int) defined class Foo scala> class Bar(v: Int, val x: Int) extends Foo(v) defined class Bar scala> new Bar(1, 1) == new Bar(1, 1) res25: Boolean = true scala> new Bar(1, 1) == new Bar(1, 2) res26: Boolean = true // ????

De Verdad? Bar(1,1) es igual a Bar(1,2) ? Esto es inesperado. Pero espera, hay más:

scala> new Bar(1,1) == Foo(1) res27: Boolean = true scala> class Baz(v: Int) extends Foo(v) defined class Baz scala> new Baz(1) == new Bar(1,1) res29: Boolean = true //??? scala> println (new Bar(1,1)) Foo(1) // ??? scala> new Bar(1,2).copy() res49: Foo = Foo(1) // ???

Una copia de Bar tiene tipo Foo ? ¿Puede ser esto correcto?

Sin duda, podemos solucionar esto sobrescribiendo el .equals (y .hashCode , y .toString , y .unapply , y .copy , y también, posiblemente, .productIterator , .productArity , .productElement , etc.) en Bar y Baz . Pero "fuera de la caja", cualquier clase que extienda una clase de caso se romperá.

Esta es la razón, ya no se puede extender una clase de caso por otra clase de caso, se ha prohibido desde entonces, creo que scala 2.11. Todavía se permite extender una clase de caso por una clase que no sea de caso, pero, al menos, en opinión de wartremover no es una buena idea.