2016-03-02 7 views
13

Ich bin sicher, dass meine Frage nicht sinnvoll, aber es ist, weil ich nicht weiß, was ich sehe oder wie es zu beschreiben ...Hat int.class autobox Klasse <Integer>

Der folgende Code kompiliert gut, aber es sollte nicht, weil int nicht der gleiche Typ wie Integer ist. Sollte das nicht einen Compilerfehler ergeben? Und wenn der Compiler den Typ Class<Integer> erwartet, wie wird er zur Laufzeit in Class<int> aufgelöst? Ist das etwas Magie, wo der Compiler es auf Primitive setzt? Und wenn der Compiler die Validierung von Primitiven lockert, führt das nicht zu Fehlern, bei denen die Methodenschreiber erwarten, dass der Typ der EXACT-Typ Class<Integer> ist und stattdessen Class<int> geliefert wird.

Kurz gesagt, warum kompiliert und produziert das correct oder wrong (je nach Perspektive) Ergebnis zur Laufzeit.

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"); 
} 

Ausgang:

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

Für die Kontrollgruppe, dieser Code tut NOT COMPILE wie ich

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 { 
} 

Fehler erwarten:

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

immer Fehler erwähnen, wenn ein [MCVE] bietet, gibt es 2 Fehler beim Kompilieren: 'Main.java:13: Fehler: inkompatible Typen: Klasse kann nicht in Klasse umgewandelt werden printClass ("Employee", Employee.class); 'und' Main.java:14: error: Unvergleichbare Typen: Class und Class System.out.printf ("AreEqual:% s ", Person.class == Employee.class);' – Ferrybig

+0

Weil es bei Objekten nicht kompiliert wird (siehe das Beispiel der Person). Warum funktionieren Primitive anders als Objekte?Insbesondere muss der Typ, der an die Methode übergeben wird, für alle anderen Fälle GENAU übereinstimmen, mit Ausnahme des primitiven Falls, der mit int beschrieben wurde. – leat

Antwort

15

Was Sie beachten ist ein direktes Ergebnis der Art und Weise Generika Primitiven handhaben, ist es nicht auto-Boxen. Um konsistent in Fällen zu sein, in denen Klasseninformationen verwendet werden (wie Generika oder Reflektion), müssen primitive Typen in bestimmten Fällen mit etwas zurückkehren, wenn sie ihren Typ untersuchen.

Bei der Dereferenzierung von anyprimitivetype.class wird das Feld TYPE aus der einschließenden Wrapper-Klasse zurückgegeben. In Ihrem Fall ist es:

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

Sie die vollständige Liste hier für die ganze primitive Art finden und nichtig: primitives

Sie sind Teil der Sprache spec seit 1.1 sind.

+0

Danke !! Ich habe gerade ein anderes Beispiel eingegeben, um zu zeigen, dass es nicht autoboxing ist (zumindest im herkömmlichen Sinne), da Autoboxing zur Kompilierzeit konvertiert wird, also hätte meine Laufzeitausgabe nicht "int" gesagt, sondern stattdessen "Integer" ' – leat

3

dort Da implizite Autoboxing ist schon seit Java 5 von primitiven Typen. Für andere Typen müssen Sie eine andere Syntax verwenden, um Ihr Ziel zu erreichen: Suchen Sie nach Generics.

Try this:

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

Die 'Class' Objekte werden nicht autoboxiert. – dimo414

+1

@ dimo414: Die akzeptierte Antwort ist eine bessere Methode als meine (ich habe sie upvolotiert). Aber für Anfänger kann es schwierig sein zu verstehen. – Xvolks

3

Das ist, weil dies die Java Generics Arbeit Weg. Wenn Sie alle Klassen zulassen möchten, die von Person erben Sie verwenden:

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

Dies beantwortet die Frage nicht. – dimo414

Verwandte Themen