SORU
5 Mayıs 2010, ÇARŞAMBA


Ham bir türü nedir ve neden't kullanıyoruz?

Soru:

  • Java, çiğ çeşitleri nelerdir ve neden genellikle yeni bir kod içinde kullanılması gerektiğini duyuyorum?
  • Eğer raw türlerini kullanabilir miyiz, bunun alternatifi nedir ve nasıl daha iyi?

Benzer sorular

CEVAP
5 Mayıs 2010, ÇARŞAMBA


Ham bir türü nedir?

Java Dil Belirtimi tanımlarçiğ yazınaşağıdaki gibi

JLS 4.8 Raw Types

Ham bir türü olarak tanımlar

  • Genel türde bir beyan adını beraberindeki gerçek tür parametreler olmadan kullanılan.
  • Bir üst sınıftan miras veya R superinterface olmayan ham bir tür R statik olmayan her tür üyesi.

Burada göstermek için bir örnek:

public class MyType<E> {
    class Inner { }
    static class Nested { }

    public static void main(String[] args) {
        MyType mt;          // warning: MyType is a raw type
        MyType.Inner inn;   // warning: MyType.Inner is a raw type

        MyType.Nested nest; // no warning: not parameterized type
        MyType<Object> mt1; // no warning: type parameter given
        MyType<?> mt2;      // no warning: type parameter given (wildcard OK!)
    }
}

Burada, MyType<E>parametreli yazın(JLS 4.5). Kısaca sadece MyType olarak halk dilinde bu tür başvurmak için yaygındır, ama teknik olarak adı MyType<E>.

mt tanımı da ikinci madde işareti noktası tarafından çiğ bir türü ham bir türü (ve derleme bir uyarı oluşturur) yukarıdaki ilk kurşun nokta vardır.

MyType.Nested parametrik türü static çünkü 16 ** üyesi, bir tür olmasına rağmen, parametrik türü değildir.

** 18 mt2 ham tipler gibi değil yani hem gerçek tür parametreleri ile bildirilir.


Çiğ türleri hakkında bu kadar özel olan ne?

Esasen, çiğ türleri jenerik tanıtıldı daha önce olduğu gibi davranır. Yani, aşağıdaki derleme zamanı tamamen yasaldır.

List names = new ArrayList(); // warning: raw type!
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // not a compilation error!

Yukarıdaki kod gayet iyi, ama aynı zamanda aşağıdaki varsayalım: çalışır

for (Object o : names) {
    String name = (String) o;
    System.out.println(name);
} // throws ClassCastException!
  //    java.lang.Boolean cannot be cast to java.lang.String

Şimdi names instanceof String olmayan bir şeyi içerdiğinden çalıştırma, başımız belaya girerse,.

names String içermesini isterseniz muhtemelenolabilirbelki de hala ham bir türü kullanınel ile her kontrol edinadd kendinizi, ve sonrasadece el attı27 ** names her öğe.Hatta daha iyiama kullanmak için DEĞİL bir çiğ yazınderleyici için izin verinJava jenerik ve gücünü.

List<String> names = new ArrayList<String>();
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // compilation error!

Eğer tabiiYAPIN** 32, ve yukarıdaki kod derleme gibi names bildirebilirsiniz ** 31, o zaman izin vermek istiyor.

Ayrıca Bkz


Ne tür parametreleri olarak ham bir tür <Object> kullanarak farklı

Aşağıdaki bir alıntıEtkili Java 2. Baskı, Madde 23: yeni kod çiğ türleri Yok:

Sadece 34* *ham tip 35 ** parametreli tür arasındaki fark nedir? Gevşek konuşma, ikincisi açıkça herhangi bir türdeki nesneleri tutma kapasitesine sahip olan derleyici söylerken genel tür denetimi dışında kalmayı tercih etti. Türü parametresi için List<String> pas yapabiliyorken List, 38* *türünde bir parametre için bunu yapamazsın. Jenerik için kistlerinin alt tiplerinin belirlenmesindeki kuralları vardır, ve List<String> parametreli tip List<Object> 40 ** ama çiğ değil bu tür çalışmaları devam ediyor. Sonuç olarakeğer List ama eğer parametrik türü kullanıyorsanız List<Object> gibi değil gibi raw kullanırsanız tipi emniyet kaybedersiniz.

Bu noktada göstermek için, List<Object> aldığı aşağıdaki yöntemi deneyin ve new Object() ekler.

void appendNewObject(List<Object> list) {
   list.add(new Object());
}

Java jenerik değişmez. List<String> aşağıdaki derleyici bir uyarı üretecek kadar List<Object> bir:

List<String> names = new ArrayList<String>();
appendNewObject(names); // compilation error!

Eğer appendNewObject çiğ bir tür parametre olarak List ilan olsaydı, o zaman bu derleme, ve bu nedenle jenerik almış olduğunuz bu tür güvenlik kaybedersin.

Ayrıca Bkz


Nasıl ham bir tür parametre olarak <?> kullanmadan farkı var?

*, List<String>, *55 vb sadece List bunun yerine onlar sadece söylemek için cazip olabilir, böylece 57**,. List<E> add(E), List<?> sadece herhangi bir rasgele nesne ekleyemezsiniz sadece tanımlar beri. ancak, büyük bir fark var: Raw türü List tür güvenliği olmadığı için diğer taraftan, 63 ** List bir şey.

Önceki parçacığın: aşağıdaki varyasyon göz önünde bulundurun

static void appendNewObject(List<?> list) {
    list.add(new Object()); // compilation error!
}
//...

List<String> names = new ArrayList<String>();
appendNewObject(names); // this part is fine!

Derleyici olarak yazın List<?> değişmezliği ihlal koruyan harika bir iş yaptı! Eğer raw türünü parametre olarak ilan etmiş olsaydı List list, kod derleme ve tür List<String> names değişmeyen ihlal edersin.


Eğer güvenli değil ise, neden bir raw yazın kullanmak için izin verilir mi?

İşte İDEA dan bir alıntı 4.8:

Ham türlerinin kullanımını sadece eski kod uyumluluk için bir imtiyaz olarak izin verilir.Kod çiğ türleri, Java programlama diline genericity girişten sonra yazılı kullanımı kesinlikle önerilmez. Java programlama dili sürümlerini ham türlerinin kullanımını engellemek mümkündür.

2. Baskı etkili Javaayrıca bu eklemek için:

Çiğ türleri kullanmamalısın o yüzden dil tasarımcılar onlara izin verdi? Uyumluluk sağlamak için.

Java platformu jenerik kullanılmaya başlandı ikinci on yılına girmek üzereydi ve jenerik kullanan varlığını Java kod büyük bir miktar vardı. Tüm bu kod jenerik kullanan yeni bir kod ile yasal ve birlikte kalan kritik olarak görüldü. Yasal olması için sıradan bir tip ile kullanmak için, ve tam tersi tasarlanmış yöntemler parametreli türler örnekleri geçmesi gerekiyordu. Bu gereksinim, olarak bilinirgöç uyumlulukraw türlerini destekleme kararı sürdü.

Özetle, çiğ türleri ASLA yeni bir kod kullanılmalıdır.Her zaman parametreli türleri kullanmalısınız.


Hiç istisna yok mu?

Java jenerik olmayan şeyleşiyor, çünkü ne yazık ki, çiğ türleri yeni bir kod kullanılmalıdır iki istisnası vardır:

  • Sınıf rakamları List.class örneğin, List<String>.class değil
  • instanceof, o instanceof Set örneğin, o instanceof Set<String> değil işlenen

Ayrıca Bkz

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • EvilControllers

    EvilControll

    20 Ocak 2008
  • Marques Brownlee

    Marques Brow

    21 Mart 2008
  • PhoneBuff

    PhoneBuff

    10 HAZİRAN 2011