Any, AnyVal, AnyRef, Object arasındaki ilişkiler nelerdir ve Java kodunda kullanıldıklarında nasıl eşlenirler?


111

Genelde derlenene kadar her kombinasyonu denerim. Biri neyi nerede kullanmam gerektiğini açıklayabilir mi?

Yanıtlar:


125

Chris'in cevabına bir açıdan katılmayacağım . Sınıflar Any, AnyRefve AnyVal vardır sınıflar. Ancak, JVM'nin içsel sınırlamaları nedeniyle bayt kodunda sınıflar olarak görünmezler.

Bu, Java'daki her şeyin bir nesne olmadığı gerçeğinden kaynaklanmaktadır. Nesnelere ek olarak, ilkeller var. Java'daki tüm nesneler neslinin altındadır java.lang.Object, ancak ilkel öğeler ayrıdır ve şu anda * bir programcı tarafından genişletilemez. Ayrıca, ilkellerin yöntemlere değil, "işleçlere" sahip olduğuna dikkat edin.

Scala'da ise her şey bir nesnedir, tüm nesneler bir sınıfa aittir ve yöntemler aracılığıyla etkileşime girerler. Oluşturulan JVM bayt kodu bunu yansıtmaz, ancak bu, bayt kodunda olmasa bile, Java'nın jeneriklere sahip olması gibi, onları daha az yapmaz.

Dolayısıyla, Scala'da tüm nesnelerin nesli vardır Anyve bu, hem Java'nın nesneler olarak gördüklerini hem de Java'nın ilkel olarak gördüklerini içerir. Java'da eşdeğeri yoktur çünkü böyle bir birleşme yoktur.

Java'da ilkel sayılan her şey AnyValScala'dan gelmektedir. Scala 2.10.0 AnyValmühürlenene ve programcılar bunu genişletemeyene kadar. .Net üzerinde Scala ile ne olacağını görmek ilginç olmalı, çünkü tek başına birlikte çalışabilirlik Scala'nın en azından kullanıcı tanımlı "ilkelleri" tanımasını gerektiriyor.

Ayrıca genişletme Any, AnyRefeşdeğerdir java.lang.Object(herhangi bir oranda JVM'de).

Scala 2.9.x'e kadar, bir kullanıcı onları genişletemedi Anyveya AnyValJava'dan referans veremedi , ancak Scala'da kullanılabilecek başka kullanımlar da vardı . Özellikle tip imzaları:

def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)

Her birinin ne anlama geldiği, sınıf hiyerarşisinden anlaşılır olmalıdır. Ancak dikkat edilmesi gereken nokta, bu fve hotomatik kutuya galınacak , ancak olmayacak. Bu, Java'nın yaptığının biraz tersidir fve hbelirtilemez ve g(ile tanımlanır java.lang.Object) otomatik kutulamaya neden olur.

Scala 2.10.0'dan başlayarak, kullanıcı aşağıdaki anlamlarla AnyValveya Anyaşağıdaki anlamlarla genişletebilir :

  • Bir sınıf genişlerse AnyVal, belirli koşullar altında öbek üzerinde onun için bir örnek oluşturulmaz. Bu, bu sınıfın alanlarının (2.10.0'da sadece tek bir alana izin verildiği - bu değişip değişmeyeceği görülmeye devam edecek), ister ilkel olsun, isterse diğer nesnelere referans olsun, yığın üzerinde kalacağı anlamına gelir. Bu, örnekleme maliyeti olmadan genişletme yöntemlerine izin verir.

  • Bir özellik uzanıyorsa Any, o zaman her iki uzanan sınıfları ile birlikte kullanılabilir AnyRefuzanan ve sınıfları AnyVal.

Not: Benim görüşüme göre, Java muhtemelen "yapı" ilkellerine ve belki de yazı tiplerine izin verirken C # 'ı takip edecek, çünkü onlara başvurmadan paralellik iyi bir performansla başarmanın zor olduğu ortaya çıkıyor.


2
Güncelleme: Scala 2.9.2'den itibaren AnyValolarak tanımlanmıştır sealed trait AnyVal extends Any. Ama Scala 2.10 bu değişti abstract class AnyVal extends Any with NotNullve uzatmak artık mümkün AnyValyeni değer sınıfları özelliği olan, örneğin: class MyValue(val u: Int) extends AnyVal.
ebruchez

@ebruchez Not için teşekkürler. Cevabımı yeni yeteneklere genel bir bakışla güncelledim.
Daniel C. Sobral

Nothing ve Null bununla nasıl ilişkili?
Gaurav Khare


5

Anyve AnyValinanıyorum ki, scala tipi sistemin bir parçası ve sınıflar değiller (aynı şekilde Nothingbir tip, bir sınıf değil). Bunları Java kodu içinden açıkça kullanamazsınız.

Bununla birlikte, Java / Scala birlikte çalışmasında, Java'yı kabul eden bir yöntem Objectbir scala Any/ AnyRef.

Gerçekte ne yapmaya çalışıyorsun?


Bu konuyu daha iyi anlamaya çalışıyorum, böylece Java'nın Scala'yı çağırmasını veya tam tersini yapmayı planladığımda hangi türü kullanmam gerektiğini biliyorum. Bu cevap stackoverflow.com/questions/2334200/… ve AnyRefalıcısı bana bunun benim için hala gizemli olduğunu hatırlattı.
huynhjl
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.