Di Jawa, saya ingin memiliki sesuatu sebagai:
class Clazz<T> {
static void doIt(T object) {
// ...
}
}
Tapi saya mengerti
Tidak dapat membuat referensi statis ke tipe T non-statis
Saya tidak mengerti obat generik di luar penggunaan dasar dan karenanya tidak bisa memahaminya. Tidak membantu bahwa saya tidak dapat menemukan banyak info di internet tentang masalah ini.
Bisakah seseorang mengklarifikasi jika penggunaan semacam itu dimungkinkan, dengan cara yang serupa? Juga, mengapa upaya awal saya tidak berhasil?
sumber
Java tidak tahu apa
T
itu sampai Anda instantiate jenis.Mungkin Anda bisa menjalankan metode statis dengan menelepon
Clazz<T>.doit(something)
tetapi sepertinya Anda tidak bisa.Cara lain untuk menangani berbagai hal adalah dengan memasukkan parameter tipe dalam metode itu sendiri:
yang tidak memberi Anda batasan yang tepat pada U, tapi itu lebih baik daripada tidak sama sekali ....
sumber
Saya mengalami masalah yang sama. Saya menemukan jawaban saya dengan mengunduh kode sumber untuk
Collections.sort
dalam kerangka java. Jawaban yang saya gunakan adalah untuk meletakkan<T>
generik dalam metode, bukan dalam definisi kelas.Jadi ini berhasil:
Tentu saja, setelah membaca jawaban di atas saya menyadari bahwa ini akan menjadi alternatif yang dapat diterima tanpa menggunakan kelas generik:
sumber
T extends XXX
sintaksis.Comparable
. Coba<T extends Comparable<? super T>>
saja.Dimungkinkan untuk melakukan apa yang Anda inginkan dengan menggunakan sintaks untuk metode generik ketika mendeklarasikan
doIt()
metode Anda (perhatikan penambahan di<T>
antarastatic
danvoid
dalam tanda tangan metodedoIt()
):Saya mendapat editor Eclipse untuk menerima kode di atas tanpa
Cannot make a static reference to the non-static type T
kesalahan dan kemudian memperluasnya ke program kerja berikut (lengkap dengan referensi budaya yang agak sesuai usia):Yang mencetak garis-garis ini ke konsol ketika saya menjalankannya:
sumber
<T>
menutupi yang pertama dengan cara yang sama bahwa dalamclass C { int x; C(int x) { ... } }
parameterx
menutupi bidangx
.static <E extends SomeClass> E foo(E input){return input;}
untuk setiap metode ketika saya ingin melakukan sesuatu sepertistatic <E extends SomeClass>; //static generic type defined only once and reused
static E foo(E input){return input;}
static E bar(E input){return input;}
//...etc...
Saya pikir sintaks ini belum disebutkan (jika Anda ingin metode tanpa argumen):
Dan panggilannya:
Semoga ini bisa membantu seseorang.
sumber
<String>
karena hanya menyimpulkan argumen tipe karena Anda menetapkannya ke variabel. Jika Anda tidak menetapkannya, itu hanya menyimpulkanObject
.Disebut dengan benar dalam kesalahan: Anda tidak dapat membuat referensi statis ke tipe T. non-statis. Alasannya adalah parameter tipe
T
dapat diganti oleh salah satu argumen tipe misalnyaClazz<String>
atauClazz<integer>
dll Tapi bidang statis / metode yang dimiliki oleh semua non objek-statis dari kelas.Kutipan berikut diambil dari dokumen :
Seperti yang ditunjukkan oleh chris dalam jawabannya, Anda perlu menggunakan tipe parameter dengan metode dan bukan dengan kelas dalam kasus ini. Anda bisa menulis seperti:
sumber
Sesuatu seperti yang berikut ini akan membuat Anda lebih dekat
Sunting: Contoh yang diperbarui dengan lebih detail
sumber
Ketika Anda menentukan tipe generik untuk kelas Anda, JVM tahu tentang itu hanya memiliki turunan kelas Anda, bukan definisi. Setiap definisi hanya memiliki tipe parametrized.
Generik berfungsi seperti templat di C ++, jadi pertama-tama Anda harus membuat instance kelas Anda, lalu gunakan fungsi dengan tipe yang ditentukan.
sumber
Clazz<int>::doIt( 5 )
)Juga untuk membuatnya secara sederhana, itu terjadi karena properti "Penghapusan" dari obat generik. Yang berarti bahwa meskipun kita mendefinisikan
ArrayList<Integer>
danArrayList<String>
, pada waktu kompilasi, ia tetap sebagai dua jenis beton yang berbeda tetapi pada saat runtime JVM menghapus jenis generik dan hanya membuat satu kelas ArrayList, bukan dua kelas. Jadi ketika kita mendefinisikan metode tipe statis atau apa pun untuk generik, itu dibagi oleh semua contoh generik itu, dalam contoh saya itu dibagi oleh keduanyaArrayList<Integer>
danArrayList<String>
. Itulah sebabnya Anda mendapatkan kesalahan. Parameter Tipe Generik dari Kelas Tidak Diizinkan dalam Konteks Statis!sumber
@BD di Rivenhill: Karena pertanyaan lama ini telah mendapat perhatian baru tahun lalu, mari kita lanjutkan sedikit, hanya demi diskusi. Tubuh
doIt
metode Anda tidak melakukan apa-apa-T
spesifik sama sekali. Ini dia:Jadi, Anda dapat sepenuhnya menghapus semua variabel tipe dan hanya kode
Baik. Tapi mari kita kembali lebih dekat ke masalah aslinya. Variabel tipe pertama pada deklarasi kelas adalah redundan. Hanya metode kedua yang diperlukan. Kita mulai lagi, tetapi ini bukanlah jawaban terakhir:
Namun, semuanya terlalu ribut tentang apa-apa, karena versi berikut berfungsi dengan cara yang sama. Yang dibutuhkan hanyalah tipe antarmuka pada parameter metode. Tidak ada variabel tipe yang terlihat di mana pun. Apakah itu benar-benar masalah awal?
sumber
Karena variabel statis dibagikan oleh semua instance kelas. Misalnya jika Anda memiliki kode berikut
T tersedia hanya setelah sebuah instance dibuat. Tetapi metode statis dapat digunakan bahkan sebelum instance tersedia. Jadi, parameter tipe umum tidak dapat dirujuk di dalam metode dan variabel statis
sumber