Ik probeer meestal elke combinatie totdat deze is gecompileerd. Kan iemand uitleggen wat ik waar moet gebruiken?
Antwoord 1, autoriteit 100%
Ik ben het niet eens met Chris’santwoordin één opzicht. De klassen Any
, AnyRef
en AnyVal
zijnklassen. Maar ze verschijnen niet als klassen in bytecode, vanwege intrinsieke beperkingen van de JVM.
Dit komt voort uit het feit dat niet alles in Java een object is. Naast objecten zijn er primitieven. Alle objecten in Java zijn afstammelingen van java.lang.Object
, maar primitieven zijn apart gezet en, momenteel*, niet uitbreidbaar door een programmeur. Merk ook op dat primitieven “operators” hebben, geen methoden.
In Scala daarentegen is alles iseen object, behoren alle objecten tot een klasse en werken ze samen via methoden. De gegenereerde JVM-bytecode weerspiegelt dit niet, maar dat maakt ze niet minder, net zoals Java generieke varianten heeft, ook al heeft de bytecode ze niet.
Dus in Scala zijn alle objecten afstammelingen van Any
, en dat omvat zowel wat Java als objecten beschouwt als wat Java als primitieven beschouwt. Er is geen equivalent in Java omdat zo’n unificatie niet bestaat.
Alles wat in Java als primitief wordt beschouwd, stamt af van AnyVal
in Scala. Tot Scala 2.10.0 was AnyVal
verzegeld en konden programmeurs het niet verlengen. Het zou interessant moeten zijn om te zien wat er zal gebeuren met Scala op .Net, aangezien alleen interoperabiliteit Scala vereist om op zijn minst door de gebruiker gedefinieerde “primitieven” te herkennen.
Het uitbreiden van Any
is AnyRef
, wat gelijk is aan java.lang.Object
(in ieder geval op de JVM).
p>
Tot Scala 2.9.x kon een gebruiker Any
of AnyVal
niet uitbreiden, noch ernaar verwijzen vanuit Java, maar er warenandere waarvoor ze in Scala kunnen worden gebruikt. Typ handtekeningen in het bijzonder:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
Wat elk betekent, moet duidelijk zijn uit de klassenhiërarchie. Van belang is echter dat f
en h
automatisch worden ingesloten, maar g
niet. Dat is een beetje het tegenovergestelde van wat Java doet, in die zin dat f
en h
niet gespecificeerd kunnen worden, en g
(gedefinieerd met java.lang.Object
) zou auto-boxing veroorzaken.
Vanaf Scala 2.10.0 kan de gebruiker echter AnyVal
of Any
uitbreiden met de volgende semantiek:
-
Als een klasse
AnyVal
uitbreidt, wordt er onder bepaalde voorwaarden geen instantie voor op de heap gemaakt. Dit betekent dat de velden van deze klasse (op 2.10.0 is slechts één veld toegestaan – of dat zal veranderen valt nog te bezien) op de stapel blijven staan, of het nu primitieven zijn of verwijzingen naar andere objecten. Dit maakt uitbreidingsmethoden mogelijk zonder de kosten voor het maken van een instantie. -
Als een eigenschap
Any
uitbreidt, kan het worden gebruikt met zowel klassen dieAnyRef
uitbreiden als klassen dieAnyVal
uitbreiden.
PS: Naar mijn mening zal Java waarschijnlijk C# volgen bij het toestaan van “struct”-primitieven, en misschien typedefs, omdat parallellisme zonder er gebruik van te maken moeilijk blijkt te zijn met goede prestaties.
Antwoord 2, autoriteit 34%
Dit gezien? De tekst van de pagina bevat enkele opmerkingen over Java-interoperabiliteit.
http://www.scala-lang.org/node/128
Antwoord 3, autoriteit 4%
Any
en AnyVal
zijn, geloof ik, onderdeel van het scala type systeemen zijn geen klassen als zodanig(op dezelfde manier dat Nothing
een type is, geen klasse). Je kunt ze niet expliciet gebruiken vanuit Java-code.
Echter, in Java/Scala-interoperatie, verwacht een methode die een Java Object
accepteert een scala Any
/ AnyRef
.
Wat probeer je eigenlijk te doen?