Jika IDE saya sangat cerdas, mengapa saya harus menggunakan "clone ()"?

13

Tipe IDE ( NetBeans ) saya memeriksa Collectionskode saya saat saya mengetik. Tetapi kemudian, mengapa saya harus melemparkan objek yang dikembalikan Object.clone()? Itu baik saja. Tidak ada salahnya tidak busuk. Tapi tetap saja, saya tidak mengerti.

Apakah pengecekan tipe, tanpa casting, objek yang dikembalikan Object.clone()tidak mungkin? The generik kerangka membuat saya berpikir IDE bisa memeriksa jenis referensi objek pada sisi kanan dari " = " mark tanpa casting sementara saya mengetik? Saya tidak mengerti.

addendum
Kasus penggunaan saya hanya karena saya memiliki Calendarbidang pribadi , pubdate . Saya akan menulis:

Calendar getPubdate() {
    return pubdate;
}

tapi ada risiko bahwa Invoker bisa memodifikasi saya pubdate , jadi saya kembali salinan:

Calendar getPubdate() {
    return (Calendar) pubdate.clone();
}

Kemudian, saya bertanya-tanya mengapa saya harus memilih pubdate.clone(). Metode signature memiliki tipe di sana. NetBeans harus bisa mengetahuinya. Dan NetBeans tampaknya melakukan sesuatu yang mirip dengan itu Collections.

konishiki
sumber
5
Contoh kode pendek (!) Akan sangat membantu.
Doc Brown
78
IDE terpisah dari bahasa itu sendiri, jadi seberapa pintar Netbeans tidak berpengaruh pada cara kerja bahasa Java.
JacquesB
7
Catatan, karena kembali jenis kovarians, dianjurkan untuk kembali MyObjectdari clone()daripada Object- ini menghilangkan seluruh masalah ini. Lebih lanjut dianjurkan untuk tidak pernah menggunakan clone()(Item Java Efektif # 11).
Boris the Spider
Apakah penekanan pertanyaan Anda pada I atau pada 'cast "clone ()"' ? Karena pertanyaan yang dihasilkan dari mantan mungkin sebenarnya pertanyaan yang jauh lebih baik daripada dari yang terakhir.
user541686
Ketika saya membaca judul pertanyaan, satu-satunya hal yang saya pikirkan adalah this.clone()pada objek programmer, terutama pada malam Wed setelah rilis Tue. Maaf, tetapi saya harus menulis komentar ini. Mengapa IDE tidak pintar hanya memperbaiki semua bug untuk kami LOL
Mai

Jawaban:

53

mengapa saya harus melemparkan objek yang dikembalikan Object.clone()?

Karena itu kembali Object.

The generik kerangka membuat saya berpikir IDE bisa memeriksa jenis referensi objek pada sisi kanan dari " = " mark tanpa casting sementara saya mengetik? Saya tidak mengerti.

Object.clone tidak generik.

Jika obat generik telah ada ketika clonedirancang, mungkin akan terlihat seperti ini (menggunakan F-Bounded Polymorphism):

interface Cloneable<T extends Cloneable<T>> {
  T clone();
}

Jika Java memiliki fitur MyType, mungkin akan terlihat seperti ini:

interface Cloneable {
  this clone();
}

Tapi Generik tidak ada saat Object.clonedirancang, dan Java tidak memiliki MyTypes, jadi versi yang tidak aman Object.cloneadalah yang harus kita gunakan.

Jörg W Mittag
sumber
Saya baru menyadari bahwa fitur IDE yang membingungkan saya adalah kompilasi latar belakang? Maksud saya, itulah yang memungkinkan penyelesaian kode dan pengecekan tipe otomatis dengan obat generik? Secara pribadi, saya lebih suka menunda memeriksa jenis sampai kompilasi eksplisit. Tapi saya suka menyelesaikan kode.
konishiki
1
@konishiki dengan Java 8 (dan sampai batas tertentu Java 7) ketik inferensi , untuk memberikan bantuan, IDE perlu menyimpulkan tipe. Ini membutuhkan kompilasi sebagian. Sebelum mengetik inferensi, kompilasi tidak diperlukan untuk pelengkapan otomatis.
Boris the Spider
@ BoristheSpider Terima kasih banyak atas umpan balik itu! Saya pasti perlu melakukan beberapa pengujian / pemikiran lagi. sangat dihargai.
konishiki
Mengapa Anda harus lulus original?
Clashsoft
@Clashsoft: Thinko bodoh sambil mengadaptasi versi Pemrograman Fungsional yang jelas. Terima kasih.
Jörg W Mittag
26

Ini bukan fitur dari IDE apa pun, tetapi dari definisi bahasa.

Sebuah IDE membantu Anda menggunakan bahasa pemrograman lebih efisien, itu tidak mengubah semantik bahasa itu. Itu berarti bahwa bantuan editor mungkin secara otomatis memasukkan gips ketika sudah jelas yang mana yang Anda inginkan, tetapi itu tidak bisa begitu saja melanggar aturan bahasa dan berpura-pura bahwa kode yang tidak dikompilasi valid.

Sunting Memang benar bahwa suatu IDE dapat membundel kompilernya sendiri, dan pada kenyataannya banyak yang melakukan hal itu, misalnya untuk pelaporan kesalahan yang lebih baik dengan lebih banyak informasi orang dalam ke dalam pohon parse parsial. Namun, itu akan menjadi ide yang sangat buruk untuk membiarkan kompiler internal ini menerapkan semantik bahasa yang berbeda dari SDK resmi, karena itu berarti bahwa kode yang berfungsi dalam pengembangan dapat secara misterius mulai gagal ketika dipasang di produksi - menghasilkan masalah yang menurut definisi tidak debuggable!

Kilian Foth
sumber
Inilah yang terjadi: Saya cukup yakin penyelesaian kode adalah fitur IDE (dilakukan melalui refleksi). Dan pengecekan tipe otomatis yang saya bicarakan terjadi di IDE (melalui kompilasi latar belakang). Saya harap itulah yang sedang terjadi.
konishiki
1
IDE dapat dengan mudah melanggar semua aturan spesifikasi bahasa dan hanya mengkompilasi kode. Saya tahu NetBeans dan Eclipse menggunakan kompiler mereka sendiri, misalnya. Jadi dalam kasus-kasus IDE dan kompiler secara efektif adalah hal yang sama. Tidak mengatakan itu ide yang bagus, tetapi kompiler C tentu melakukannya sepanjang waktu.
MichaelS
@MichaelS Spesifikasi bahasa C dirancang untuk memungkinkan variasi yang signifikan antara implementasi, sehingga vendor yang berbeda dapat memilih antara berbagai pendekatan yang mungkin dan menambahkan fitur tambahan. Ini menciptakan berbagai bidang ambiguitas dalam spesifikasi, yang diperlukan untuk memungkinkan variasi tersebut. Nama "C" tidak memiliki merek dagang, jadi tidak ada yang mengontrol penggunaan istilah ini. Spesifikasi Java dirancang untuk menghilangkan ambiguitas sebanyak mungkin, dan Java adalah merek dagang dan pemegang merek dagang menegaskan bahwa itu hanya dapat digunakan dalam implementasi yang sesuai.
Jules
IDE modern memerlukan kompiler. Petunjuk kelengkapan kode mengharuskan kode sebelum kursor diuraikan. Dan tentunya dengan obat generik (atau template C ++) yang membutuhkan kompiler lengkap, bukan hanya pengurai.
MSalters
3

Ini karena tipe tanda tangan dari metode Object.clone. Tipe tanda tangan menyatakan bahwa metode akan mengembalikan objek tipe Objek.

protected Object clone() throws CloneNotSupportedException

Koleksi akan menggunakan tipe generik yang disebut untuk menggantikan jenis casting secara otomatis.

Jadi, jika Anda memiliki kode ini:

List<Integer> ints = Arrays.asList(1,2,3);
int x = ints.get(0);`

kompiler akan menambahkan gips untuk Anda di belakang layar, sehingga kodenya akan menjadi:

List ints = Arrays.asList(1,2,3);
int x = (Integer)ints.get(0);
Miro
sumber
0

Untuk kelengkapan, sejak Java 5, tipe pengembalian kovarian diizinkan . Jadi, Anda dapat menulis yang berikut ini:

public MyObject implements Cloneable {
  @Override
  public MyObject clone() {
    try {
      return (MyObject)super.clone();
    } catch (CloneNotSupportedException e) {
      throw new AssertionError();
    }
  }
}

Dengan ini, kode berikut ini legal:

MyObject original = new MyObject();
MyObject clone = original.clone();
Olivier Grégoire
sumber