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 .R
R
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>
.
mt
yukarıdaki tanımdaki ilk madde işareti noktasına göre ham bir türe sahiptir (ve bir derleme uyarısı üretir); inn
ayrıca üçüncü mermi noktasına göre ham bir türe sahiptir.
MyType.Nested
parametreli bir türün üye türü olmasına rağmen parametreli bir tür değildir MyType<E>
, çünkü static
.
mt1
, ve mt2
her 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ü names
olmayan bir şey içeriyor instanceof String
.
İstersen Tahminen, names
sadece 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 String
her öğ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 names
bir izin Boolean
, o zaman olarak ilan edebilir List<Object> names
ve 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
List
ve 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ündeList
bir 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!
appendNewObject
Ham türü List
parametre 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 List
bunun 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 List
tip güvenliği olmadığından, add
hemen 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 list
kod 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
static
bir ham türün yapıcısı, örnek yöntemi veya alan dışıC
tü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 static
alanlar 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
, getNames
bir 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ı ads
ve 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>.class
instanceof
operand, ö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
, TypeName
dü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>.class
JLS'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ı Collections
ve onlar düzenlenen Objects
hiçbir şey daha az şey. İstenen tipe Collections
kadar her işlem Object
istenilen 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;}
}
CompareAble
Arabirimin compareTo(MyCompareAble)
ham türlerle uygulanmasının imkansız olduğunu unutmayın . Bunları neden kullanmamalısınız:
Object
saklananlar Collection
kullanılmadan önce dökülmelidirObject
Derleyici 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. CompareAble
Arayüzde ne olacağından emin değilim , sanırım iki compareTo
işlev yaratıyor , biri a MyCompareAble
ve diğeri bir alıyor Object
ve 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, Box
genel 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 Box
olursunuz - 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. @SuppressWarnings
Sö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.
List
Destek 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 List
yerine 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, list
somutlaş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 Integer
veya 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> arr
Tür Nesnesine başvuran ArrayList
türden bir referans değişkendir . Bu sadece String tipi Object tutabileceği anlamına gelir.String
ArralyList
String
Bu bir Sıkı olan String
bir 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> arr
katı 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 arr
Sıkı bir tür. Yani, a eklerken derleme zamanı hatasını yükseltir integer
.
Uyarı : -
Raw
Tür Nesnesi,Strict
Başvurulan Değişken türüne başvurulurArrayList
.
Bu durumda ArrayList arr
ham türdür, ancak new ArrayList<String>();
Nesneniz Katı türdür.
arr.add("hello");
arr.add(23); //compiles fine but raise the warning.
arr
Ham Tür olduğu için içine herhangi bir Nesne türü ekleyecektir .
Uyarı : - A
Strict
Tipi Nesneye,raw
Değ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 double
bir olması gerekiyordu ne içine Set
bir int
s.
Set set = new HashSet();
set.add(3.45); //ok
Eşyaları alırken, Set
ne çıktığını bilmiyorsunuz. Diyelim ki bunların hepsinin olmasını bekliyorsunuz int
, bunu yapıyorsunuz Integer
; double
3.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 list
bir olan List
unespecified 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 List
burada uygun dönüş türüdür.