La première différence pratique est que vals paresseux et les objets sont paresseux, alors que vals sont impatients. La principale différence entre les objets et les vals paresseux est qu'un objet est, du point de vue des langages, considéré comme un "singleton", qui, du point de vue de jvm, est généralement considéré comme un membre statique.La définition d'objet dans l'exemple donné ne peut pas être redéfinie, comme d'autres l'ont démontré, pour la même raison que les membres statiques ne peuvent pas être remplacés: sans être lié à une instance, il n'y a pas moyen de faire une recherche de fonction virtuelle.
object Foo { object Bar extends A; }
est vaguement comme le code java suivant:
class Foo {
private static class Bar extends A{}
public static Bar Bar = new Bar;
}
Si dans l'exemple ci-dessus, si une sous-classe C étend Foo a été définie, il ne serait pas en mesure de passer outre la définition de Bar. La barre d'instance statique en Java serait accessible en tant que Foo.Bar. C.Bar ne veut pas dire la même chose que (nouveau C) .Bar. Je pourrais être un peu hors ici, je n'ai pas réellement essayé de dé-compiler le code de scala, ceci est juste un exemple pour illustrer le concept général des objets en tant que membres statiques.
les vals paresseux peuvent être un peu moins efficaces. La dernière fois que j'ai vérifié, ils ont été implémentés en maintenant un champ caché dans la classe qui gardait la trace des vals paresseux qui avaient été initialisés. La maintenance de ce champ nécessite un verrouillage, ce qui peut entraîner des problèmes de performances.
Une grande différence pratique entre val paresseux et l'objet est le traitement de l'échec:
Si j'ai:
class Foo() { throw new Exception("blah!"); }
object Stuff { object Bar extends Foo { val x = "hi" } }
Stuff.Bar
//exception "blah!" thrown.
Stuff.Bar.x
//NoClassDefFoundError: Could not initialize Stuff$Bar$
alors que si je fais:
object Stuff2 { lazy val Bar = new Foo() { val x = "hi" } }
Stuff2.Bar
// "blah!"
Stuff2.Bar.x
// "blah!"
Le "NoClassDefFoundError" peut être vraiment déroutant, et puisque c'est une erreur et non une exception, il peut casser le code de gestion des erreurs qui attrape (logiquement)/logs "Exception" mais permet aux erreurs de se propager. Je pourrais même considérer ce genre de bug dans le langage Scala, car ce cas d'utilisation indique en fait une condition exceptionnelle, pas vraiment une erreur JVM. J'ai vu NoClassDefFoundErrors lors de l'accès aux objets qui dépendaient de ressources externes (par exemple, les connexions à la base de données ou les fichiers sur le disque). Seul le premier accès enregistre la cause sous-jacente. Par conséquent, le débogage correct d'un tel problème nécessite généralement de redémarrer votre serveur d'applications.
Il s'avère que 'valent val a3 = nouveau A {def foo = 1}' aurait dû aussi être ajouté à la question. – PeWu
Voir aussi [Scala - new vs object extends] (http://stackoverflow.com/q/16182735/1048572) – Bergi