97 votes

Pourquoi `private val` et` private final val` sont-ils différents?

J'ai l'habitude de penser qu' private val et private final val sont même, jusqu'à ce que j'ai vu à la section 4.1 de la Scala de Référence:

Une valeur constante de la définition est de la forme

final val x = e

où e est une expression constante (§6.24). Le dernier modificateur doit être présent et sans annotation de type peut être donné. Les références à la valeur de la constante x sont eux-mêmes traités comme des expressions constantes; dans le code généré, ils sont remplacés par la définition de la droite de l'e.

Et j'ai écrit un test:

class PrivateVal {
  private val privateVal = 0
  def testPrivateVal = privateVal
  private final val privateFinalVal = 1
  def testPrivateFinalVal = privateFinalVal
}

javap -c sortie:

Compiled from "PrivateVal.scala"
public class PrivateVal {
  public int testPrivateVal();
    Code:
       0: aload_0       
       1: invokespecial #19                 // Method privateVal:()I
       4: ireturn       

  public int testPrivateFinalVal();
    Code:
       0: iconst_1      
       1: ireturn       

  public PrivateVal();
    Code:
       0: aload_0       
       1: invokespecial #24                 // Method java/lang/Object."<init>":()V
       4: aload_0       
       5: iconst_0      
       6: putfield      #14                 // Field privateVal:I
       9: return
}

Le byte-code est juste que Scala de Référence, a déclaré: private val n'est private final val.

Pourquoi ne pas scalac de traitement, private val comme private final val? Est-il une raison sous-jacente?

80voto

Steve Waldman Points 3854

Donc, c'est juste une supposition, mais c'était une plante vivace de la gêne en Java final variables statiques avec un littéral sur le côté droit de l'obtenir incorporé dans le bytecode comme des constantes. Qui engendre un gain de performances, bien sûr, mais il provoque la compatibilité binaire de la définition de rompre si la "constante" a jamais changé. Lors de la définition d'une finale statique de la variable dont la valeur peut-être besoin de changer, de programmeurs Java, le recours à des hacks comme initialisation de la valeur avec une méthode ou d'un constructeur.

Val-de la Scala est déjà la finale de la Java sens. Il ressemble à la Scala, les designers sont à l'aide de la redondante modificateur final qui signifie "l'autorisation aux commandes de la valeur de la constante". Scala programmeurs ont le contrôle complet sur ce problème sans avoir recours à des hacks: s'ils veulent un inline constante, une valeur qui ne doit jamais changer, mais est rapide, ils écrivent "final val". si ils veulent de la flexibilité pour modifier la valeur sans casser la compatibilité binaire, juste "val".

8voto

Connor Doyle Points 929

Je pense que la confusion provient de la fusion de l'immuabilité avec la sémantique de final. val s peuvent être remplacés dans les classes enfants et ne peuvent donc pas être traités comme finaux à moins d'être marqués comme tels explicitement.

@Brian Le REPL fournit une étendue de classe au niveau de la ligne. Voir:

 scala> $iw.getClass.getPackage
res0: Package = package $line3

scala> private val x = 5
<console>:5: error: value x cannot be accessed in object $iw
  lazy val $result = `x`

scala> private val x = 5; println(x);
5
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X