Sorular:
- Java'da ham türler nelerdir ve neden yeni kodlarda kullanılmamaları gerektiğini sık sık duyuyorum?
- Ham türleri kullanamıyorsak alternatif nedir ve nasıl daha iyidir?
Yanıtlar:
Java Dil Belirtimi ham türü aşağıdaki gibi tanımlar :
Ham tür aşağıdakilerden biri olarak tanımlanır:
Eşlik eden tür bağımsız değişken listesi olmadan genel tür bildirimi adı alınarak oluşturulan başvuru türü.
Öğe türü ham tür olan bir dizi türü.
Öğesinin üst sınıfından veya üst yüzeyinden miras alınmayan
staticüye olmayan bir ham tür .RR
Aşağıda açıklamak için bir örnek verilmiştir:
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>bir olduğunu parametreli tip ( JLS 4.5 ). Halk dilinde bu tipe kısaca kısaca değinmek yaygındır MyType, ancak teknik olarak isimdir MyType<E>.
mtyukarıdaki tanımdaki ilk madde işareti noktasına göre ham bir türe sahiptir (ve bir derleme uyarısı üretir); innayrıca üçüncü mermi noktasına göre ham bir türe sahiptir.
MyType.Nestedparametreli bir türün üye türü olmasına rağmen parametreli bir tür değildir MyType<E>, çünkü static.
mt1, ve mt2her ikisi de gerçek tür parametreleriyle bildirildiğinden, bunlar ham tür değil.
Temel olarak, ham türler tıpkı jenerik ilaç kullanılmadan önceki gibi davranır. Yani, derleme zamanında aşağıdakiler 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 çalışıyor, ancak aşağıdakilere de sahip olduğunuzu varsayalım:
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 çalışma zamanında sorun yaşıyoruz, çünkü namesolmayan bir şey içeriyor instanceof String.
İstersen Tahminen, namessadece içerdiği String, sen olabilir belki hala ham türü kullanmak ve her kontrol elle add kendinizi ve sonra elle dökme için Stringher öğenin names. Daha da iyisi , ham bir tür kullanmak DEĞİLDİR ve derleyicinin sizin için tüm işleri yapmasına izin vermek, Java jeneriklerinin gücünü kullanmaktadır.
List<String> names = new ArrayList<String>();
names.add("John");
names.add("Mary");
names.add(Boolean.FALSE); // compilation error!
Eğer değilse, doğal DO istediğiniz namesbir izin Boolean, o zaman olarak ilan edebilir List<Object> namesve yukarıdaki kod derlemek olacaktır.
<Object>tür parametresi olarak kullanılmasından farkı nedir?Effective Java 2nd Edition, Item 23'ten bir alıntı : Yeni kodda ham türleri kullanmayın :
Ham tip
Listve parametreli tip arasındaki farkList<Object>nedir? Gevşek bir şekilde, birincisi genel tip kontrolünü devre dışı bırakırken, ikincisi derleyiciye herhangi bir türdeki nesneyi tutabildiğini açıkça söyledi. AList<String>türündeListbir parametreye geçebilse de, türdeki bir parametreye iletemezsinizList<Object>. Jenerikler için alt tipleme kuralları vardırList<String>ve ham tipin bir alt tipidirList, ancak parametrelenmiş tipte değildirList<Object>. Sonuç olarak, gibi ham tür kullanırsanız tür güvenliğini kaybedersinizList, ancak gibi parametreli bir tür kullanırsanız tür güvenliğini kaybedersinizList<Object>.
Noktayı göstermek için, a alan List<Object>ve a ekleyen aşağıdaki yöntemi göz önünde bulundurun new Object().
void appendNewObject(List<Object> list) {
list.add(new Object());
}
Java'daki jenerikler değişmezdir. A List<String>bir değildir List<Object>, bu nedenle aşağıdakiler derleyici uyarısı oluşturur:
List<String> names = new ArrayList<String>();
appendNewObject(names); // compilation error!
appendNewObjectHam türü Listparametre olarak almayı bildirdiyseniz , bu derlenir ve bu nedenle jeneriklerden aldığınız tür güvenliğini kaybedersiniz.
<?>tür parametresi olarak kullanılmasından farkı nedir?List<Object>,, List<String>vs. hepsi List<?>, bu yüzden sadece Listbunun yerine olduklarını söylemek cazip gelebilir . Bununla birlikte, büyük bir fark vardır: List<E>sadece bir tanımladığından add(E), a'ya herhangi bir keyfi nesne ekleyemezsiniz List<?>. Öte yandan, ham tipin Listtip güvenliği olmadığından, addhemen hemen her şeyi yapabilirsiniz List.
Önceki snippet'in aşağıdaki varyasyonunu düşünün:
static void appendNewObject(List<?> list) {
list.add(new Object()); // compilation error!
}
//...
List<String> names = new ArrayList<String>();
appendNewObject(names); // this part is fine!
Derleyici, sizi potansiyel tipinin değişmezliğini ihlal etmekten korumak için harika bir iş çıkardı List<?>! Parametreyi ham tür olarak bildirdiyseniz, List listkod derlenir ve tür değişmezini ihlal ederdiniz List<String> names.
JLS 4.8'e geri dön:
Bir tür olarak kullanmak mümkündür silinmesini parametreli bir türü ya da eleman türü parametreli bir türü olan bir dizi türü sılme. Böyle bir türe ham tip denir .
[...]
Ham tipin üst sınıfları (sırasıyla üst sınıflar), genel tipteki parametrelerin herhangi birinin üst sınıflarının (üst sınıfları) silinmeleridir.
Üst sınıflarından veya üst sınıflarından miras alınmayan
staticbir ham türün yapıcısı, örnek yöntemi veya alan dışıCtürü, karşılık gelen genel bildirimde türünün silinmesine karşılık gelen ham türdürC.
Daha basit bir çiğ türü kullanılıyor terimler, yapıcılar, örnek yöntemlerde ve sivil olarak staticalanlar vardır da silinir .
Aşağıdaki örneği alın:
class MyType<E> {
List<String> getNames() {
return Arrays.asList("John", "Mary");
}
public static void main(String[] args) {
MyType rawType = new MyType();
// unchecked warning!
// required: List<String> found: List
List<String> names = rawType.getNames();
// compilation error!
// incompatible types: Object cannot be converted to String
for (String str : rawType.getNames())
System.out.print(str);
}
}
Biz çiğ kullandığınızda MyType, getNamesbir ham döndüren böylece, sıra silinir olur List!
JLS 4.6 aşağıdakileri açıklamaya devam eder:
Tür silme ayrıca bir kurucu veya yöntemin imzasını, parametrelenmiş tür veya tür değişkeni olmayan bir imzayla eşler. Bir kurucunun veya yöntem imzasının silinmesi
s, aynı adsve verilen tüm resmi parametre türlerinin silinmesinden oluşan bir imzadırs.Bir yöntemin dönüş türü ve genel bir yöntemin veya kurucunun tür parametreleri de, yöntemin veya kurucunun imzası silinirse silinir.
Genel bir yöntemin imzasının silinmesinin hiçbir tür parametresi yoktur.
Aşağıdaki hata raporu, derleyici geliştirici Maurizio Cimadamore ve JLS'nin yazarlarından Alex Buckley'den bu tür davranışların neden ortaya çıkması gerektiğine dair bazı düşünceler içeriyor: https://bugs.openjdk.java.net/browse / JDK-6400189 . (Kısacası, spesifikasyonu kolaylaştırır.)
İşte JLS 4.8'den başka bir alıntı:
Ham türlerin kullanımına yalnızca eski kodun uyumluluğundan taviz olarak izin verilir. Java programlama diline jenerikliğin girilmesinden sonra yazılan kodda ham türlerin kullanılması kesinlikle önerilmez. Java programlama dilinin gelecekteki sürümlerinin ham türlerin kullanımına izin vermemesi mümkündür.
Etkili Java 2nd Edition ayrıca şunları eklemek için:
Ham türleri kullanmamanız gerektiği göz önüne alındığında, dil tasarımcıları neden onlara izin verdi? Uyumluluk sağlamak.
Java platformu, jenerikler tanıtıldığında ikinci on yılına girmek üzereydi ve jenerikler kullanmayan muazzam miktarda Java kodu vardı. Tüm bu kodların yasal ve jenerik ilaç kullanan yeni kodlarla birlikte çalışabilir olması kritik kabul edildi. Parametreli türlerin örneklerini sıradan türlerle kullanılmak üzere tasarlanmış yöntemlere geçirmek yasal olmalıdır (tersi de geçerlidir). Göç uyumluluğu olarak bilinen bu gereklilik, ham türleri destekleme kararını vermiştir.
Özetle, ham tipler ASLA yeni kodda kullanılmamalıdır. Her zaman parametreli tipler kullanmalısınız .
Ne yazık ki, Java jenerikleri birleştirilmediğinden, ham türlerin yeni kodda kullanılması gereken iki istisna vardır:
List.class, değilList<String>.classinstanceofoperand, örneğin o instanceof Set, değilo instanceof Set<String>o instanceof Set<?>ham türden kaçınmasına da izin verilir (ancak bu durumda sadece yüzeyseldir).
n, her bir uygulama sınıfı için aynı kodla uzak fasulye yazma ihtiyacını çözer .
TypeName.class, TypeNamedüz bir tanımlayıcı ( jls ). Varsayımsal olarak konuşmak gerekirse, sanırım gerçekten de olabilir. Belki bir ipucu olarak, List<String>.classJLS'nin özellikle bir derleyici hatası çağırdığı varyanttır, bu yüzden dilin içine eklerse, kullandıkları tek şey olmasını beklerdim.
Java'da ham türler nelerdir ve neden yeni kodlarda kullanılmamaları gerektiğini sık sık duyuyorum?
Ham türler Java dilinin eski tarihidir. Başlangıçta vardı Collectionsve onlar düzenlenen Objectshiçbir şey daha az şey. İstenen tipe Collectionskadar her işlem Objectistenilen tipte.
List aList = new ArrayList();
String s = "Hello World!";
aList.add(s);
String c = (String)aList.get(0);
Bu çoğu zaman işe yararken, hatalar meydana geldi
List aNumberList = new ArrayList();
String one = "1";//Number one
aNumberList.add(one);
Integer iOne = (Integer)aNumberList.get(0);//Insert ClassCastException here
Eski daktilo koleksiyonları tip güvenliğini zorlayamadı, bu yüzden programcı bir koleksiyon içinde ne sakladığını hatırlamak zorunda kaldı.
Bu sınırlamanın üstesinden gelmek için icat edilen jenerikler, geliştirici depolanan türü bir kez beyan eder ve derleyici bunu yapar.
List<String> aNumberList = new ArrayList<String>();
aNumberList.add("one");
Integer iOne = aNumberList.get(0);//Compile time error
String sOne = aNumberList.get(0);//works fine
Karşılaştırma için:
// Old style collections now known as raw types
List aList = new ArrayList(); //Could contain anything
// New style collections with Generics
List<String> aList = new ArrayList<String>(); //Contains only Strings
Karşılaştırılabilir arayüz daha karmaşık:
//raw, not type save can compare with Other classes
class MyCompareAble implements CompareAble
{
int id;
public int compareTo(Object other)
{return this.id - ((MyCompareAble)other).id;}
}
//Generic
class MyCompareAble implements CompareAble<MyCompareAble>
{
int id;
public int compareTo(MyCompareAble other)
{return this.id - other.id;}
}
CompareAbleArabirimin compareTo(MyCompareAble)ham türlerle uygulanmasının imkansız olduğunu unutmayın . Bunları neden kullanmamalısınız:
Objectsaklananlar Collectionkullanılmadan önce dökülmelidirObjectDerleyici ne yapar: Generics geriye dönük olarak uyumludur, ham türlerle aynı java sınıflarını kullanırlar. Sihir çoğunlukla derleme zamanında gerçekleşir.
List<String> someStrings = new ArrayList<String>();
someStrings.add("one");
String one = someStrings.get(0);
Aşağıdaki gibi derlenecektir:
List someStrings = new ArrayList();
someStrings.add("one");
String one = (String)someStrings.get(0);
Bu, ham türleri doğrudan kullandıysanız yazacağınız kodla aynıdır. CompareAbleArayüzde ne olacağından emin değilim , sanırım iki compareToişlev yaratıyor , biri a MyCompareAbleve diğeri bir alıyor Objectve onu yayınladıktan sonra ilkine geçiriyor.
Ham türlere alternatifler nelerdir: Jenerik kullanımı
Ham tür, herhangi bir tür bağımsız değişkeni olmayan genel bir sınıfın veya arabirimin adıdır. Örneğin, genel Box sınıfı göz önüne alındığında:
public class Box<T> {
public void set(T t) { /* ... */ }
// ...
}
Parametreli bir tür oluşturmak Box<T>için, formal type parametresi için gerçek bir tür bağımsız değişkeni sağlarsınız T:
Box<Integer> intBox = new Box<>();
Gerçek tür bağımsız değişkeni atlanırsa, ham türden bir tür oluşturursunuz Box<T>:
Box rawBox = new Box();
Bu nedenle, Boxgenel tipin ham türüdür Box<T>. Ancak, genel olmayan bir sınıf veya arabirim türü ham tür değildir.
Ham türler eski kodda görünür, çünkü çok sayıda API sınıfı (Koleksiyon sınıfları gibi) JDK 5.0'dan önce genel değildir. Ham türleri kullanırken, temel olarak jenerik öncesi davranışa sahip Boxolursunuz - a size verir Object. Geriye dönük uyumluluk için parametreli bir türün ham türüne atanmasına izin verilir:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox; // OK
Ancak parametrelenmiş bir türe ham tür atarsanız bir uyarı alırsınız:
Box rawBox = new Box(); // rawBox is a raw type of Box<T>
Box<Integer> intBox = rawBox; // warning: unchecked conversion
Ayrıca, karşılık gelen genel türde tanımlanan genel yöntemleri çağırmak için ham bir tür kullanırsanız bir uyarı alırsınız:
Box<String> stringBox = new Box<>();
Box rawBox = stringBox;
rawBox.set(8); // warning: unchecked invocation to set(T)
Uyarı, ham türlerin, güvenli olmayan kodun yakalanma zamanını erteleyerek genel tür denetimlerini atladığını gösterir. Bu nedenle, ham türleri kullanmaktan kaçınmalısınız.
Tür Silme bölümü, Java derleyicisinin ham türleri nasıl kullandığı hakkında daha fazla bilgi içerir.
Daha önce belirtildiği gibi, eski kodu genel kodla karıştırırken, aşağıdakine benzer uyarı mesajlarıyla karşılaşabilirsiniz:
Not: Örnek.java, denetlenmeyen veya güvenli olmayan işlemler kullanır.
Not: Ayrıntılar için -Xlint: işaretlenmemiş olarak yeniden derleyin.
Bu, aşağıdaki örnekte gösterildiği gibi ham türlerde çalışan daha eski bir API kullanılırken gerçekleşebilir:
public class WarningDemo {
public static void main(String[] args){
Box<Integer> bi;
bi = createBox();
}
static Box createBox(){
return new Box();
}
}
"İşaretlenmemiş" terimi, derleyicinin tür güvenliğini sağlamak için gereken tüm tür denetimlerini gerçekleştirmek için yeterli tür bilgisine sahip olmadığı anlamına gelir. Derleyici bir ipucu verse de, "denetlenmemiş" uyarısı varsayılan olarak devre dışıdır. Tüm "işaretlenmemiş" uyarıları görmek için -Xlint: işaretlenmemiş olarak yeniden derleyin.
Önceki örneği -Xlint ile yeniden derlemek: işaretsiz aşağıdaki ek bilgileri gösterir:
WarningDemo.java:4: warning: [unchecked] unchecked conversion
found : Box
required: Box<java.lang.Integer>
bi = createBox();
^
1 warning
İşaretlenmemiş uyarıları tamamen devre dışı bırakmak için -Xlint: -unchecked bayrağını kullanın. @SuppressWarnings("unchecked")Ek açıklama kontrolsüz uyarıları bastırır. @SuppressWarningsSözdizimine aşina değilseniz, Ek Açıklamalar sayfasına göz atın.
Orijinal kaynak: Java Eğiticileri
Java'daki "raw" türü, tür güvenli olmayan genel tür parametreleri yerine "raw" Nesneleriyle ilgilenen bir sınıftır.
Örneğin, Java jenerikleri kullanılabilir olmadan önce şöyle bir koleksiyon sınıfı kullanırsınız:
LinkedList list = new LinkedList();
list.add(new MyObject());
MyObject myObject = (MyObject)list.get(0);
Nesnenizi listeye eklediğinizde, ne tür bir nesne olduğu umurumda değildir ve listeden aldığınızda, beklediğiniz türe açıkça atamanız gerekir.
Jenerikleri kullanarak "bilinmeyen" faktörünü kaldırırsınız, çünkü listede hangi tür nesnelerin gidebileceğini açıkça belirtmeniz gerekir:
LinkedList<MyObject> list = new LinkedList<MyObject>();
list.add(new MyObject());
MyObject myObject = list.get(0);
Jenerikler ile get çağrısından gelen nesneyi yayınlamanız gerekmediğine dikkat edin, koleksiyon sadece MyObject ile çalışmak üzere önceden tanımlanmıştır. Bu gerçek jenerikler için ana itici faktördür. Çalışma zamanı hatalarının kaynağını derleme zamanında kontrol edilebilen bir şeye dönüştürür.
?hala tip güvenliği sağlar. Cevabımda ele aldım.
private static List<String> list = new ArrayList<String>();
Type parametresini belirtmelisiniz.
Uyarı, jenerikleri desteklemek için tanımlanan türlerin ham formlarını kullanmak yerine parametrelendirilmesi gerektiğini önermektedir.
ListDestek jenerik tanımlanır: public class List<E>. Bu, derleme zamanı denetlenen birçok tür güvenli işleme izin verir.
private static List<String> list = new ArrayList<>();
Ham tür nedir ve neden yeni kodda kullanılmamaları gerektiğini sık sık duyuyorum?
"Ham tür", parametreli tür (ler) i için tür bağımsız değişkenleri belirtmeden genel bir sınıfın kullanılmasıdır, örneğin Listyerine List<String>. Jenerikler Java'ya dahil edildiğinde, çeşitli sınıflar jenerikleri kullanacak şekilde güncellendi. Bu sınıfı "raw type" olarak kullanmak (type argümanı belirtmeden) eski kodun derlenmesine izin verdi.
"Ham tipler" geriye dönük uyumluluk için kullanılır. Yeni kodda kullanımları önerilmez çünkü bir sınıf argümanıyla genel sınıf kullanmak daha güçlü yazmaya izin verir, bu da kodun anlaşılabilirliğini artırabilir ve potansiyel sorunları daha erken yakalamaya yol açabilir.
Ham türleri kullanamıyorsak alternatif nedir ve nasıl daha iyidir?
Tercih edilen alternatif, uygun sınıf argümanıyla (örneğin List<String>) jenerik sınıfları amaçlandığı gibi kullanmaktır . Bu, programcının türleri daha spesifik olarak belirtmesine izin verir, gelecekteki koruyucular için bir değişkenin veya veri yapısının amaçlanan kullanımı hakkında daha fazla anlam ifade eder ve derleyicinin daha iyi tip güvenliği sağlamasına izin verir. Bu avantajlar birlikte kod kalitesini artırabilir ve bazı kodlama hatalarının girişini önlemeye yardımcı olabilir.
Örneğin, programcının 'names' adlı bir List değişkeninin yalnızca Dizeler içerdiğinden emin olmak istediği bir yöntem için:
List<String> names = new ArrayList<String>();
names.add("John"); // OK
names.add(new Integer(1)); // compile error
polygenelubricants"raw type" referanslarını stackoverflow.com/questions/2770111/… 'den kendi cevabım içine kopyalamak çok cazip , ama sanırım bunları kendi cevabında kullanmak üzere bırakacağım.
Derleyici şunu yazmanızı istiyor:
private static List<String> list = new ArrayList<String>();
çünkü aksi takdirde, listsomutlaştırmayı new ArrayList<String>()anlamsız hale getirerek, istediğiniz herhangi bir türü ekleyebilirsiniz . Java jenerikleri yalnızca derleme zamanı özelliğidir, bu nedenle ile oluşturulan bir nesne new ArrayList<String>()mutlu bir şekilde kabul edilir Integerveya JFrame"ham tür" referansına atanırsa öğeler List- nesnenin kendisi hangi türleri içermesi gerektiği hakkında hiçbir şey bilmez, sadece derleyici yapar.
Burada kavramı açıklığa kavuşturabileceğiniz birden fazla durumu göz önünde bulunduruyorum
1. ArrayList<String> arr = new ArrayList<String>();
2. ArrayList<String> arr = new ArrayList();
3. ArrayList arr = new ArrayList<String>();
ArrayList<String> arrTür Nesnesine başvuran ArrayListtürden bir referans değişkendir . Bu sadece String tipi Object tutabileceği anlamına gelir.StringArralyListString
Bu bir Sıkı olan Stringbir Ham Tipi yüzden, Bir uyarı yükseltmek asla değildir.
arr.add("hello");// alone statement will compile successfully and no warning.
arr.add(23); //prone to compile time error.
//error: no suitable method found for add(int)
Bu durumda ArrayList<String> arrkatı bir türdür, ancak Nesneniz new ArrayList();ham bir türdür.
arr.add("hello"); //alone this compile but raise the warning.
arr.add(23); //again prone to compile time error.
//error: no suitable method found for add(int)
İşte arrSıkı bir tür. Yani, a eklerken derleme zamanı hatasını yükseltir integer.
Uyarı : -
RawTür Nesnesi,StrictBaşvurulan Değişken türüne başvurulurArrayList.
Bu durumda ArrayList arrham türdür, ancak new ArrayList<String>();Nesneniz Katı türdür.
arr.add("hello");
arr.add(23); //compiles fine but raise the warning.
arrHam Tür olduğu için içine herhangi bir Nesne türü ekleyecektir .
Uyarı : - A
StrictTipi Nesneye,rawDeğişken referanslı bir türe başvurulur.
Bir ham tipi bir eksikliğidir tür parametresi bir genel türü kullanırken.
Bir ekleme gibi, çalışma zamanı hataları neden olabilir çünkü Ham tipi kullanılmamalıdır doublebir olması gerekiyordu ne içine Setbir ints.
Set set = new HashSet();
set.add(3.45); //ok
Eşyaları alırken, Setne çıktığını bilmiyorsunuz. Diyelim ki bunların hepsinin olmasını bekliyorsunuz int, bunu yapıyorsunuz Integer; double3.45 geldiğinde çalışma zamanında istisna .
Türünüze bir type parametresi eklendiğinde Set, derleme hatası alırsınız. Bu önleyici hata, çalışma zamanı sırasında bir şey patlamadan önce sorunu gidermenizi sağlar (böylece zamandan ve emekten tasarruf sağlar).
Set<Integer> set = new HashSet<Integer>();
set.add(3.45); //NOT ok.
Ham türlerin sizi ısıtacağı başka bir durum:
public class StrangeClass<T> {
@SuppressWarnings("unchecked")
public <X> X getSomethingElse() {
return (X)"Testing something else!";
}
public static void main(String[] args) {
final StrangeClass<String> withGeneric = new StrangeClass<>();
final StrangeClass withoutGeneric = new StrangeClass();
final String value1,
value2;
// Compiles
value1 = withGeneric.getSomethingElse();
// Produces compile error:
// incompatible types: java.lang.Object cannot be converted to java.lang.String
value2 = withoutGeneric.getSomethingElse();
}
}
Kabul edilen cevapta belirtildiği gibi, ham tür kodunda jeneriklere tüm desteği kaybedersiniz. Her tip parametresi silinmesine dönüştürülür (yukarıdaki örnekte sadece Object).
Ne söyleyerek aşağıdadır olmasıdır listbir olan Listunespecified nesnelerin. Java listenin içinde ne tür nesneler olduğunu bilmiyor. Daha sonra listeyi yinelemek istediğinizde, o öğenin özelliklerine (bu durumda, String) erişebilmek için her öğeyi yayınlamanız gerekir.
Genel olarak koleksiyonları parametreleştirmek için daha iyi bir fikirdir, bu nedenle dönüşüm sorunlarınız yoktur, yalnızca parametrelenmiş türdeki öğeleri ekleyebileceksiniz ve düzenleyiciniz size uygun yöntemleri seçecektir.
private static List<String> list = new ArrayList<String>();
Ham tür, herhangi bir tür bağımsız değişkeni olmayan genel bir sınıfın veya arabirimin adıdır. Örneğin, genel Box sınıfı göz önüne alındığında:
public class Box<T> {
public void set(T t) { /* ... */ }
// ...
}
Parametreli bir Box türü oluşturmak için, T tipi resmi parametre için gerçek bir tür bağımsız değişkeni sağlarsınız:
Box<Integer> intBox = new Box<>();
Gerçek tür bağımsız değişkeni atlanırsa, ham bir Kutu türü oluşturursunuz:
Box rawBox = new Box();
Ham türlerden kaçının
Ham türler, bir tür parametresi belirtmeden genel bir türün kullanılmasını ifade eder.
Örneğin ,
Liste ham türken, List<String>parametrelenmiş türdür.
JDK 1.5'te jenerikler tanıtıldığında, ham türler yalnızca eski Java sürümleriyle geriye dönük uyumluluğu korumak için tutuldu. Ham türleri kullanmak hala mümkün olsa da,
Kaçınılmalıdır :
Daha az ifade edicidirler ve parametreli tiplerle aynı şekilde kendi kendilerini belgelemezler Örnek
import java.util.*;
public final class AvoidRawTypes {
void withRawType() {
//Raw List doesn't self-document,
//doesn't state explicitly what it can contain
List stars = Arrays.asList("Arcturus", "Vega", "Altair");
Iterator iter = stars.iterator();
while (iter.hasNext()) {
String star = (String) iter.next(); //cast needed
log(star);
}
}
void withParameterizedType() {
List < String > stars = Arrays.asList("Spica", "Regulus", "Antares");
for (String star: stars) {
log(star);
}
}
private void log(Object message) {
System.out.println(Objects.toString(message));
}
}Referans için : https://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html
Bu sayfayı bazı örnek alıştırmalar yaptıktan ve tam olarak aynı şaşkınlığa kavuştuktan sonra buldum.
============== Bu koddan örnek olarak sağladım ===============
public static void main(String[] args) throws IOException {
Map wordMap = new HashMap();
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
countWord(wordMap, args[i]);
}
} else {
getWordFrequency(System.in, wordMap);
}
for (Iterator i = wordMap.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
System.out.println(entry.getKey() + " :\t" + entry.getValue());
}
====================== Bu kod için ========================
public static void main(String[] args) throws IOException {
// replace with TreeMap to get them sorted by name
Map<String, Integer> wordMap = new HashMap<String, Integer>();
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
countWord(wordMap, args[i]);
}
} else {
getWordFrequency(System.in, wordMap);
}
for (Iterator<Entry<String, Integer>> i = wordMap.entrySet().iterator(); i.hasNext();) {
Entry<String, Integer> entry = i.next();
System.out.println(entry.getKey() + " :\t" + entry.getValue());
}
}
================================================== =============================
Daha güvenli olabilir ama felsefeyi bozmak 4 saat sürdü ...
Ham türler, ifade etmek istediklerinizi ifade ettiklerinde iyidir.
Örneğin, bir serileştirme işlevi bir List , ancak listenin öğe türünü bilmez. Yani Listburada uygun dönüş türüdür.