2014-05-20 19 views
7

this question için çözümlerle uğraşırken, bazı derleyici uyarılarına sahip olan aşağıdaki kodla geldim. Bir uyarı: Bu uyarı görünür neden geldiğimden anlamıyorumGenel yöntem, güvenlik hatası türünü tetikler - neden?

Type safety: The expression of type Test.EntityCollection needs unchecked conversion to conform to Test.EntityCollection<Test.Entity>

. Bir Class<M> türünü geçirerek ve yöntem EntityCollection<M> döndürdüğünü bildirerek, (Java 7) derleyicisini doğru türün iade edildiğine ikna etmek için neden yeterince yapmıyorum?

static class Entity { 
} 

static class EntityCollection<E extends Entity> { 

    private EntityCollection(HashMap<?, E> map) { 
    } 

    public static <T extends HashMap<?, M>, M extends Entity> EntityCollection<M> getInstance(
      Class<T> mapType, Class<M> entityType) 
      throws ReflectiveOperationException { 

     T map = mapType.getConstructor().newInstance(); 
     return new EntityCollection<M>(map); 
    } 
} 

public static void main(String[] args) throws Exception { 
    // both compiler warnings are on the line below: 
    EntityCollection<Entity> collection = EntityCollection.getInstance(
      LinkedHashMap.class, Entity.class); 
} 

Herhangi biri uyarıları tamamen önlemek için kodu artırabilirse, bonus puanları. Bir süredir ona bakıyorum ve uyarıları azaltmanın herhangi bir yolunu hayal etmedim.

+0

Hmm:

Yani, sen benzediğini şekilde bu kısıtlamayı değiştirmek için Kodunuza ne yapmaları gerektiğini tahmin Buna itiraz etmek için 8 (yeni bir "EntityCollection (map)') dönüşünde "bir elmas çıkarımı kullanabilirsiniz". Bunun dışında çok mutlu. Ben netbeans kullanıyorum –

+0

@RichardTingle Ben komut satırında 'javac -Xlint: all' ile derlerseniz bana uyarı vermek için Java 1.8.0_05 alabilirsiniz. –

cevap

3

Sorun şu ki, getInstance genel bir yöntemdir, ancak genel tür parametrelerini ona aktarmıyorsunuz. Böyle bunları geçirerek etrafında alabilirsiniz: Hala LinkedHashMap bir genel tür olduğu için bir rawtypes uyarı uğraşmak zorunda kalacak

public static void main(String[] args) throws Exception { 
     EntityCollection<Entity> collection = EntityCollection.<LinkedHashMap, Entity>getInstance(
       LinkedHashMap.class, Entity.class); 
    } 

. Bu durum, anahtarında anahtarında bir joker karakter olduğundan sorunludur.

Burada birçok problemle karşı karşıya:

Böyle parametreli sınıf nesneleri geçemez: LinkedHashMap<Object, Entity>.class böylece hemen hemen rawtypes uyarı ile sıkışmış.

+0

Bu açıklama için teşekkürler. Sınıf entityType argümanımın gereksiz olduğunu ve değişikliklerinizi yaptıktan sonra bunu mutlu bir şekilde kaldırabileceğimi unutmayın. –

+0

Yani asıl sorun, bu yöntemin her çağırma bir uyarı üretir ve onları yönteme taşırsanız onları bastırmak için istekli misiniz? –

+0

Çoğunlukla, bu uyarının neden alındığını anlamakla ilgilendim, dolayısıyla kabul ettiğim cevabı aldınız. Claudio'nun cevabı, uyarıların daha kolay bastırılabileceğinden dolayı uzun vadede daha faydalı olabilir. –

1

Sorun var T. T yönteminin HashMap<?, M>'u uzatması gerektiğini belirten bir kısıtlama ekliyorsunuz. Ancak, daha sonra T'ye başvurma şekliniz, Class (Class<T>) türünün genel bir parametresi gibidir. LinkedHashMap.class

A Sınıfı nesne daima olmayan bir parametreli türünü başvurur (eğer gerekli olan) değil Class<LinkedHashmap<?, Entity>> tip Class<LinkedHashMap> ait olduğunu ve mantıklı. Genel bağlama derleme zamanında varolduğundan ve çalışma zamanında bir örneğinin durumunu ve davranışını dinamik olarak yansıtmak için bu Sınıfı kullanacaksınız. Uzun lafın kısası, herhangi bir türe bağlı olmayan yeni bir örnek oluşturmak için Class<HashMap>'u kullanabilirsiniz. Java 7 veya Java ya alamayan biraz daha deney ile,

public static <T extends HashMap, M extends Entity> EntityCollection<M> getInstance(
      Class<T> mapType, Class<M> entityType) 
      throws ReflectiveOperationException { 

     T map = mapType.getConstructor().newInstance(); 
     return new EntityCollection<M>(map); 
} 
+0

Bunun, uyarıları fabrika yöntemine nasıl çektiğini beğenirim (onları @SuppressWarnings ({"rawtypes", "unchecked"}) '() ile bastırılabilirler. –

+0

Evet, uyarıları buradan tamamen kaldırmıyorum. Jenerikler Java'da çok katıdır ve sanırım böyle şeylerde yetersiz kalırlar. Ancak soru şu, gerçekten daha fazlasına mı ihtiyacımız var? Fabrika yöntemindeki uyarıyı kapsüllemek yeterince iyidir ve herhangi bir ek karmaşıklık eklemez. – Claudio

İlgili konular