Saya biasanya akhirnya mencoba setiap kombinasi sampai terkompilasi. Adakah yang bisa menjelaskan apa yang harus saya gunakan di mana?
Saya tidak akan setuju dengan jawaban Chris dalam satu hal. Kelas-kelas , dan yang kelas. Tapi mereka tidak muncul sebagai kelas dalam bytecode, karena keterbatasan intrinsik JVM.Any
AnyRef
AnyVal
Ini muncul dari fakta bahwa tidak semua yang ada di Java adalah objek. Selain objek, ada primitif. Semua objek di Java adalah turunan dari java.lang.Object
, tetapi objek primitif dipisahkan dan, saat ini * , tidak dapat dikembangkan oleh programmer. Perhatikan juga bahwa primitif memiliki "operator", bukan metode.
Di Scala, di sisi lain, semuanya adalah objek, semua objek termasuk dalam kelas, dan mereka berinteraksi melalui metode. Bytecode JVM yang dihasilkan tidak mencerminkan hal ini, tetapi itu tidak membuatnya kurang begitu, sama seperti Java yang memiliki generik, meskipun bytecode tidak memilikinya.
Jadi, di Scala, semua objek adalah turunan dari Any
, dan itu termasuk apa yang dianggap Java sebagai objek dan apa yang dianggap primitif oleh Java. Tidak ada padanan di Jawa karena tidak ada penyatuan seperti itu.
Segala sesuatu yang dianggap primitif di Jawa adalah turunan dari AnyVal
Scala. Hingga Scala 2.10.0, AnyVal
ditutup, dan pemrogram tidak dapat memperpanjangnya. Menarik untuk melihat apa yang akan terjadi dengan Scala di .Net, karena interoperabilitas saja membutuhkan Scala untuk setidaknya mengenali "primitif" yang ditentukan pengguna.
Juga memperluas Any
adalah AnyRef
, yang setara dengan java.lang.Object
(pada JVM pada setiap tingkat).
Sampai Scala 2.9.x, pengguna tidak bisa memperpanjang Any
atau AnyVal
, atau referensi mereka dari Jawa, tapi ada yang kegunaan lain mereka bisa dihukum di Scala. Secara khusus, ketik tanda tangan:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
Arti masing-masing harus jelas dari hierarki kelas. Catatan, bagaimanapun, adalah itu f
dan h
akan auto-box, tapi g
tidak akan. Itu sedikit kebalikan dari apa yang dilakukan Java, dalam hal itu f
dan h
tidak dapat ditentukan, dan g
(didefinisikan dengan java.lang.Object
) akan menyebabkan auto-boxing.
Dimulai dengan Scala 2.10.0, pengguna dapat memperluas AnyVal
atau Any
, dengan semantik berikut:
Jika sebuah kelas diperluas AnyVal
, tidak ada instance yang akan dibuat untuknya di heap dalam kondisi tertentu. Ini berarti bidang dari kelas ini (pada 2.10.0 hanya satu bidang yang diizinkan - apakah itu akan berubah masih harus dilihat) akan tetap berada di tumpukan, apakah itu primitif atau referensi ke objek lain. Ini memungkinkan metode ekstensi tanpa biaya pembuatan contoh.
Jika suatu sifat meluas Any
, maka sifat itu bisa digunakan dengan kelas yang diperluas AnyRef
dan kelas yang diperluas AnyVal
.
PS: Dalam pandangan saya sendiri, Java kemungkinan akan mengikuti C # dalam mengizinkan "struct" primitif, dan mungkin typedefs, karena paralelisme tanpa menggunakan mereka terbukti sulit dicapai dengan kinerja yang baik.
AnyVal
didefinisikan sebagaisealed trait AnyVal extends Any
. Namun dalam Scala 2.10 ini telah berubah menjadiabstract class AnyVal extends Any with NotNull
, dan sekarang mungkin untuk memperpanjangAnyVal
dengan fitur kelas nilai baru, misalnya:class MyValue(val u: Int) extends AnyVal
.Lihat ini? Teks halaman memiliki beberapa komentar interoperabilitas java. http://www.scala-lang.org/node/128
sumber
Any
danAnyVal
, saya percaya, adalah bagian dari sistem tipe scala dan bukan kelas seperti itu (dengan cara yang sama yaituNothing
tipe, bukan kelas). Anda tidak dapat menggunakannya secara eksplisit dari dalam kode Java.Namun, dalam interoperasi Java / Scala, metode yang menerima Java
Object
akan mengharapkan scalaAny
/AnyRef
.Apa yang sebenarnya Anda coba lakukan?
sumber
AnyRef
hanya mengingatkan saya bahwa ini masih misterius bagi saya.