2014-10-08 19 views
10

Aşağıdaki 3 testim var. İlk iki eser, sonuncusu değil. Bu soruyu sorma konusundaki motivasyonum, A'un B'un bir alt türü olduğu zaman B nesnesiyle aynı sınıfa sahip olacak şekilde A nesnesini atabildiğimdir.Class.class'ı temel alan ancak neden getClass tabanlı olmayan döküm?

@Test 
    public void testWorks() { 
    Object bar = "foobar"; 
    String blah = (String) bar; 
    System.out.println(blah); // Outputs foobar 
    } 

    @Test 
    public void testAlsoWorks() { 
    Object bar = "helloworld"; 
    String blah = String.class.cast(bar); 
    System.out.println(blah); // Outputs helloworld 
    } 

    @Test 
    public void testfails() { 
    Object bar = "foobar"; 
    String thetype = "hello"; 
    Class stringclass = thetype.getClass(); 
    String blah = stringclass.cast(bar); // Compiler error: incompatible types: Object cannot be converted to String                            
    System.out.println(blah); 
    } 

İlk ikisi başarılı olduğunda neden en son durumun başarısız olduğunu açıklayabilir mi, ve neden bu böyle? Ve bunu başarmak için daha iyi bir yaklaşım ne olurdu?

Class<String> stringclass = (Class<String>) thetype.getClass(); 

veya

Class<? extends String> stringclass = thetype.getClass(); 

java.lang.Class.cast(Object obj) bu Sınıfı nesnesi tarafından temsil edilen sınıf veya arayüze bir nesneyi atmalarını:

+0

Varsayalım çünkü .class derleme zamanında değerlendirildi, ancak .getClass() çalışma zamanında değerlendirilir. – odlund

+6

Derleyici, "Class <>" türetilmiş türü yerine "Class" ham türünün kullanımı konusunda sizi uyarmış olmalıydı; bu, bu bildirimle ilgili yanlış olan bir ipucunuz olabilir. – Alex

cevap

16

Sen Class tipi parametresini belirtmek gerekir.

Türü belirtmeden, derleyiciye hangi sınıfın veya arabirimin Class örneği stringclass tarafından temsil edilmediğini söylemezsiniz.

String.class numaralı telefonu aradığınızda, Class nesnesi, String türü ile dolaylı olarak parametrize edilir.

11

Java Language Specification durumları

C (§4.3), Class<C> bir sınıfı, bir arayüz veya dizi türü adıdır C.class türü,

.

Yani ifade

String.class 

tipi Class<String> olduğunu. Class, cast yönteminin döndürme türünde genel tür değişkeni kullandığı genel bir sınıftır. Yani

String.class.cast(bar); 

sonucu T Bu çağrı içinde String bağlı olan tip T, bir ifadesidir.

Object#getClass()'un dönüş türü, Class<? extends T> şeklindedir; burada T, çağrılan ifadenin silinmiş tipidir. Bu durumda

, size bir ham referans atamadan edilir Ancak

Class<? extends String> 

olduğunu. Değişken stringclass yana

Class stringclass = thetype.getClass(); 

Yani Class#cast(Object) artık String değişkene atanabilir değil Object bir dönüş tipi vardır raw, any uses of its methods that depend on the generic type variable are erased.

olduğunu.

Eğer

Class<? extends String> stringclass = thetype.getClass(); 

yapmıştı ince olurdu.

İlgili konular