2016-03-02 63 views
13

jestem pewien, że moje pytanie nie ma sensu, ale to dlatego, że nie wiem, co widzę i jak to opisać ...Czy int.class Autobox do klasy <Integer>

Poniższe kompiluje kod dobrze, ale nie powinno, ponieważ int nie jest tego samego typu co Integer. Czy nie powinno to spowodować błędu kompilatora? A jeśli kompilator oczekuje typu Class<Integer>, jak w czasie wykonywania, zostanie on rozwiązany na Class<int>? Czy jest to jakaś magia, w której kompilator pozwala działać prymitywom? A jeśli kompilator zwalnia walidację na prymitywach, nie prowadzi to do błędów, w których twórcy metod oczekują, że typ będzie typu EXACT Class<Integer>, a zamiast tego zostanie dostarczony Class<int>.

W skrócie, dlaczego ta kompilacja i generowanie correct lub wrong (w zależności od perspektywy) wynikają w czasie wykonywania.

public static void main(String[] args) { 

    printClass("int  ", int.class); 
    printClass("Integer ", Integer.class); 
    System.out.printf("AreEqual", int.class == Integer.class); 
} 

private static void printClass(String text, final Class<Integer> klazz) { 
    System.out.printf("%s: %s%s", text, klazz, "\n"); 
} 

wyjściowa:

int  : int 
Integer : class java.lang.Integer 
AreEqual: false 

dla grupy kontrolnej, ten kod robi NOT COMPILE jak spodziewałbym

public static void main(String[] args) { 

    printClass("Person ", Person.class); 
    printClass("Employee", Employee.class); 
    System.out.printf("AreEqual: %s", Person.class == Employee.class); 
} 

private static void printClass(String text, final Class<Person> klazz) { 
    System.out.printf("%s: %s%s", text, klazz, "\n"); 
} 


public class Employee extends Person { 
} 
public class Person { 
} 

błędów:

Error:(8, 40) java: incompatible types: java.lang.Class<com.company.Employee> cannot be converted to java.lang.Class<com.company.Person> 
+1

Zawsze wspominaj o błędach podczas dostarczania [MCVE], podczas kompilacji występują 2 błędy: 'Main.java:13: błąd: niekompatybilne typy: Klasa nie może zostać przekonwertowana na klasę printClass ("Pracownik", Employee.class); 'i' Main.java:14: błąd: nieporównywalne typy: Klasa i Class System.out.printf ("AreEqual:% s ", Person.class == Employee.class);' – Ferrybig

+0

Ponieważ nie kompiluje się w przypadku obiektów (patrz przykład osoby). Dlaczego prymitywy działają inaczej niż obiekty?konkretnie typ przekazany do metody musi pasować DOKŁADNIE dla WSZYSTKICH innych przypadków z wyjątkiem przypadku pierwotnego opisanego przez int. – leat

Odpowiedz

15

Co zaobserwowałeś jest bezpośrednim wynikiem sposobu rodzajowych obsługiwać prymitywów, to nie jest auto-boxing. Aby zachować spójność w przypadkach, w których będą używane informacje klasowe (np. Rodzajowe lub refleksyjne), typy pierwotne w niektórych przypadkach muszą zwracać się z czymś podczas badania ich typu.

Podczas dereferencji anyprimitivetype.class zostanie zwrócone pole TYPE z otaczającej klasy opakowania. W twoim przypadku jest to:

int.class -> public static final Class<Integer> TYPE 

można znaleźć pełną listę tutaj dla wszystkich prymitywnego rodzaju powiększonej nieważne: primitives

Są częścią specyfikacji języka od 1,1.

+0

Dziękuję! Właśnie napisałem inny przykład, aby pokazać, że to nie było autoboxing (przynajmniej w tradycyjnym sensie), ponieważ autoboxing konwertuje w czasie kompilacji, więc moje wyniki runtime nie powiedziałby "int", ale zamiast tego powiedziałby "Integer" ' – leat

3

Ponieważ istnieje niejawna autoboxing od Java 5 typów pierwotnych. W przypadku innych typów musisz użyć innej składni, aby osiągnąć swój cel: wyszukaj Generics.

Spróbuj tego:

private static void printClass(String text, final Class<? extends Person> klazz) { 
    System.out.printf("%s: %s%s", text, klazz, "\n"); 
} 
+1

Obiekty typu "Class" nie są objęte autoboxingiem. – dimo414

+1

@ dimo414: zaakceptowana odpowiedź jest o wiele lepsza niż moja (przeszedłem ją). Ale dla początkujących może to być trudne do zrozumienia. – Xvolks

3

To dlatego, że jest to sposób rodzajowych java praca. Jeśli chcesz, aby wszystkie klasy, które dziedziczą z osoba może użyć:

private static void printClass(String text, final Class<? extends Person> klazz) { 
+5

To nie odpowiada na pytanie. – dimo414

Powiązane problemy