IDE'm bu kadar akıllıysa neden “klon ()” yayınlamam gerekiyor?


13

Kod yazarken IDE ( NetBeans ) türü benim denetler Collections. Ama sonra, neden geri döndürülen nesneyi dökmem gerekiyor Object.clone()? Hangisi iyi. Zarar yok faul yok. Ama yine de anlamıyorum.

Tür denetimi, döndürülmeden döndürülen nesnenin Object.clone()mümkün olmaması mı? Jenerik çerçevesi beni IDE kontrol edebilir düşündürüyor türü "sağ tarafındaki nesne başvurularını = Yazmaya olduğum sürece döküm olmadan" işareti? Anlamıyorum.

addendum
Kullanım durumum sadece özel bir alanım olduCalendar , pubdate . Yazacaktım:

Calendar getPubdate() {
    return pubdate;
}

ancak invoker benim pubdate değiştirmek bir risk var , bu yüzden bir kopyasını döndü:

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

Sonra neden oyuncu seçmem gerektiğini merak ettim pubdate.clone(). Yöntem imzasının tam türü vardır. NetBeans bunu anlayabilmelidir. Ve NetBeans bakımından benzer bir şey yapıyor gibi görünüyordu Collections.


5
Kısa (!) Kod örneği yardımcı olacaktır.
Doc Brown

78
IDE, dilin kendisinden ayrıdır, bu nedenle akıllı Netbeans'in dilin Java üzerinde nasıl çalıştığı üzerinde hiçbir etkisi yoktur.
JacquesB

7
Dönüş türü kovaryansı nedeniyle MyObject, clone()yerine döndürülmesi önerilir Object- bu, tüm sorunu ortadan kaldırır. Ayrıca asla kullanmamanız önerilir clone()(Etkili Java Öğesi # 11).
Örümcek Boris

Sorunuzun ben mi yoksa '' cast 'clone ()' 'üzerinde mi vurgulandınız ? Çünkü birincisinden kaynaklanan soru aslında ikincisinden çok daha iyi bir soru olabilir.
user541686

Soru başlığını okuduğumda, düşündüğüm tek şey this.clone()programcının nesnesinde, özellikle Çar'nın serbest bırakılmasından sonraki Çar gecesinde. Üzgünüm ama bu yorumu yazmak zorunda .. Neden akıllı IDE sadece bizim için tüm hataları
Mai

Yanıtlar:


53

neden döndürülen nesneyi kullanmam gerekiyor Object.clone()?

Çünkü geri dönüyor Object.

Jenerik çerçevesi beni IDE kontrol edebilir düşündürüyor türü "sağ tarafındaki nesne başvurularını = Yazmaya olduğum sürece döküm olmadan" işareti? Anlamıyorum.

Object.clone jenerik değildir.

cloneTasarlanırken jenerikler mevcut olsaydı, muhtemelen şöyle görünüyordu (F Sınırlı Polimorfizm kullanarak):

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

Java bir MyType özelliğine sahip olsaydı, belki şöyle görünebilir:

interface Cloneable {
  this clone();
}

Ancak, Generics Object.clonetasarlandığında mevcut değildi ve Java'nın MyTypes'i olmadığından, türünün güvensiz versiyonu, Object.cloneçalışmak zorunda olduğumuz şeydir.


Beni şaşırtan IDE özelliğinin arka plan derlemesi olduğunu fark ettim. Yani, kod tamamlama ve jenerikler ile otomatik tip kontrolünü sağlayan nedir? Şahsen, açık bir derleme olana kadar tip kontrolünü ertelemeyi tercih ederim. Ama kod tamamlama seviyorum.
konishiki

1
@konishiki, Java 8 (ve bir dereceye kadar Java 7) türü çıkarım ile , herhangi bir yardım sağlamak için IDE'nin türleri çıkarması gerekir. Bu kısmi derleme gerektirir. Tür çıkarımından önce, otomatik tamamlama için derlemeye gerek yoktur.
Örümcek Boris

@BoristheSpider Bu geri bildirim için çok teşekkürler! Kesinlikle biraz daha test / düşünme yapmam gerekiyor. çok müteşekkirim.
konishiki

Neden geçmeniz gerekiyor original?
Clashsoft

@Clashsoft: Açık İşlevsel Programlama sürümünü uyarlarken aptalca thinko. Teşekkürler.
Jörg W Mittag

26

Bu herhangi bir IDE'nin değil, dil tanımının bir özelliğidir.

IDE bir programlama dilini daha verimli kullanmanıza yardımcı olur, o dilin anlambilimini değiştirmez. Bu, bir editör yardımcısının, hangisini istediğiniz açık olduğunda otomatik olarak bir döküm ekleyebileceği, ancak dilin kurallarını ihlal edemeyeceği ve derlenmeyen kodun geçerli olduğunu iddia edemeyeceği anlamına gelir.

Düzenle Bir IDE'nin kendi derleyicisini bir araya getirebileceği doğrudur ve aslında çoğu, örneğin kısmi ayrıştırma ağacına daha fazla iç bilgiyle daha iyi hata raporlaması için tam olarak bunu yapar. Bununla birlikte, bu dahili derleyicinin resmi SDK'dan farklı bir dil anlambilimi uygulamasına izin vermek çok kötü bir fikir olacaktır, çünkü bu, geliştirme aşamasında çalışan kodun, üretimde yüklendiğinde gizemli bir şekilde başarısız olmaya başlayabileceği anlamına gelir. debuggable!


Bu oldu: Kod tamamlamanın bir IDE özelliği (yansıma yoluyla yapılır) olduğundan eminim. Ve bahsettiğim otomatik tip kontrolü IDE'de (arka plan derlemesi yoluyla) gerçekleşiyor. Umarım olan budur.
konishiki

1
IDE olabilir çok kolay dil spec tüm kuralları kırmak ve sadece zaten kodu derlemek. Hem NetBeans hem de Eclipse'ın kendi derleyicilerini kullandığını biliyorum. Yani bu durumlarda IDE ve derleyici etkili bir şekilde aynı şeydir. Bunun iyi bir fikir olduğunu söylememekle birlikte, C derleyicileri her zaman bunu yapar.
MichaelS

@MichaelS C dili spesifikasyonu, uygulamalar arasında önemli farklılıklar sağlamak için tasarlanmıştır, böylece farklı satıcılar farklı olası yaklaşımlar arasında seçim yapabilir ve ekstra özellikler ekleyebilir. Bu, spesifikasyonda bu varyasyonlara izin vermek için gerekli olan çeşitli belirsizlik alanları yaratır. "C" ismi ticari markalı değildir, bu nedenle hiç kimse terimin kullanımını kontrol etmez. Java özelliği mümkün olduğunca belirsizliği ortadan kaldırmak için tasarlanmıştır ve Java ticari markalıdır ve ticari marka sahibi yalnızca uyumlu uygulamalarda kullanılabileceğini zorunlu kılar.
Jules

Modern IDE'lerin zaten bir derleyiciye ihtiyacı var. Kod tamamlama ipuçları, imleç ayrıştırılmadan önceki kodun bulunmasını gerektirir. Ve kesinlikle sadece bir ayrıştırıcı değil, tam bir derleyici gerektiren jenerik (veya C ++ şablonları) ile.
MSalters

3

Bunun nedeni, Object.clone yönteminin tür imzasıdır. Tür imzası, yöntemin Object türünde bir nesne döndüreceğini belirtir.

protected Object clone() throws CloneNotSupportedException

Koleksiyonlar, döküm türünü otomatik olarak değiştirmek için jenerik türler kullanacaktır.

Yani bu koda sahipseniz:

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

derleyici sizin için sahne arkasındaki oyuncuları ekler, böylece kod aslında şöyle olur:

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

0

Tamlık için, Java 5'ten beri, kovaryant dönüş türlerine izin verilir . Böylece aşağıdakileri yazabilirsiniz:

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

Bununla, aşağıdaki kod yasaldır:

MyObject original = new MyObject();
MyObject clone = original.clone();
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.