2010-01-09 14 views
6

Ich komme aus PHP Welt und bin so verwirrt darüber, wie Sie denken, wenn Sie Objekte in Java deklarieren.Nummer Wrapper-Klassen in Java

so, wenn traditionell Sie wie folgt tun:

Rectangle rect = new Rectangle(); 

Ursache rect ist ein Rechteck-Datentyp.

Laut der Java Tutorial-Seite ist eine Wrapper-Klasse eine Unterklasse von Number. So ist es eine Klasse, aber wenn man es instanziiert das Tutorial hat es wie folgt aus:

Integer x; 
x = 12; 

Warum Ist es nicht so aus wie die traditionelle Art und Weise:

Integer x = new Integer(12); 
or 
Integer x = new Integer(); 

Und hier ist ein weiteres Beispiel:

String s = new Integer(i).toString(); 

Also hier ist s ein String-Objekt. das bekomme ich. Aber du hast neue Ganzzahl (i). Warum neu? Was bedeutet es hier und was passiert, wenn es "i" an den Konstruktor sendet? Wo kann ich sehen, was der Konstruktor mit den Parametern in der Java-API macht?

Viele Fragen, aber konnte keine Quellen im Netz finden, die es erklären.

Antwort

10

Zum einen können Sie nur die primitiven Typen verwenden:

int x = 12; 
double d = 3.3456; 

Zweitens können Sie optional die Objekt-Wrapper für diese Zahlen verwenden:

Integer x = new Integer(12); 
Double d = new Double(3.3456); 

Drittens, wenn Sie die Darstellung Zeichenfolge möchten, können Sie Dazu einfach mit:

String s = Integer.toString(12); 

oder gerade:

int x; 
String s = "x = " + x; 

oder sogar printf() wie Syntax:

int x = 12; 
String s = String.format("x = %d", x); 

Schließlich Java ab Version 5 unterstützt hat Auto-Boxen und Unboxing, die Sie verwirren können, wenn Sie nicht erwartet.Zum Beispiel:

Integer i = 1234; // autoboxes int to Integer 

und

int i = new Integer(1234); // autounboxes Integer to an int 

einfach die primitiven Typen verwenden, wenn Sie die Number Wrapper benötigen. Der häufigste Grund, sie zu verwenden, ist, sie in Sammlungen zu setzen (List s, usw.).

+1

thx für eine gute Erklärung. ist String s = Integer.toString (12); das Gleiche wie String s = Integer (12) .toString(); – ajsie

+1

@danben: nein, du bist inkorrekt http://bit.ly/6Nt8D1 – cletus

7

Was Sie im ersten Beispiel sehen, heißt Autoboxing/Autounboxing. Java (ab Version 5) konvertiert automatisch zwischen 5 und Integer.valueOf(5), wodurch ein Wrapper vom Typ Integer aus einem int-Primitiv erstellt wird. Aber letzteres (Integer x = new Integer(12)) ist absolut richtig.

Es funktioniert jedoch nicht im zweiten Fall, wenn Sie etwas wie 5.toString() schreiben möchten. Autoboxing tritt nur auf, wenn einem Wrappertyp ein Grundelement zugewiesen wird oder ein Grundelement übergeben wird, für das der Wrappertyp erwartet wird usw. Primitive Typen sind keine Objekte und haben daher keine Eigenschaften, auf die verwiesen werden kann.

Re: "warum neu", weil alle Referenztypen (nicht primitive) in Java dynamisch auf dem Heap zugewiesen werden. So (Autoboxing beiseite), ist die einzige Möglichkeit, einen Integer (oder einen anderen Referenztyp) zu erhalten, explizit Speicherplatz für einen zuzuweisen.

+2

Möglicherweise ist zu beachten, dass Autoboxing eine Funktion von Java 5 ist. Wenn Sie also eine frühere Version (z. B. 1.4) verwenden, müssen Sie die neue Integer (5) -Syntax verwenden. – digitaljoel

+2

Technisch wird Autoboxing von "5" in "Integer.valueOf (5)" konvertiert. Dies ermöglicht das Teilen von Instanzen. –

+0

@Laurence Gonsalves: danke, ich habe die Korrektur gemacht – danben

1

Zusätzlich zu den Objekten enthält Java auch primitive Datentypen wie boolean, byte, int, long, char, float, double. Alle diese werden in Kleinbuchstaben bezeichnet und werden mit Literalwerten verwendet. Diese werden immer nach Wert übergeben.

Es gibt auch passende Zahlenobjekte Boolean, Byte, Integer, Long usw., die verwendet werden können, die wie alle Objekte als Referenz übergeben werden. Da es sich um Objekte und nicht um Primitive handelt, gibt es unterschiedliche Auswirkungen auf die Leistung und Merkmale, auf die Sie achten sollten.

Moderne Java hat Auto Boxen und Auto Unboxing zu leise zwischen den Primitiven und Objekte zu umwandeln, die die Syntax erlauben, wie Sie es Integer i = 5 verwendet haben Integer eine primitive 5 in ein Objekt AutoBox. Zuvor hätten Sie entweder die primitive int i = 5 oder die explizite objektbasierte Syntax Integer i = new Integer(5) anstelle von Mischtypen verwenden müssen, wie Sie es jetzt können.

2

Manches die anderen Antworten nicht angesprochen haben:

Integer x = new Integer(); 

Das wird nicht funktionieren, weil die Integer Klasse keinen Konstruktor no-args hat (was wäre int-Wert ist das resultierende Objekt?).

String s = new Integer(i).toString(); 

Also hier s ist ein String-Objekt. dass ich bekomme. Aber du hast neue Ganzzahl (i). Warum neu? Was bedeutet es hier und was passiert mit , wenn es 'i' an den Konstruktor sendet. Wo kann ich sehen, was der -Konstruktor mit den Parametern in Java-API macht?

Es bedeutet das gleiche wie oben: ein Integer Objekt erstellt wird, geleitet, um die Inhalte der Variablen i (wahrscheinlich ein Schleifenindex) als Konstruktorargument, und dann wird das resultierende Objekt toString() Methode aufgerufen wird, die einen String ergibt Darstellung der Nummer.

Wo Sie solche Dinge nachschlagen können, beschreibt die Java API doc alle Aspekte der Standard-API im Detail. Wenn das nicht genug ist, kommt Suns JDK mit dem vollständigen Quellcode der Standard-API. Wenn Sie das JDK installieren, haben Sie die Möglichkeit, diesen Quellcode zu bekommen, und die meisten IDEs erlauben Ihnen, leicht zu diesem zu springen.

+0

zeigen Netbeans einige Methodendetails während der Codierung? – ajsie

+0

Ja, versuchen Sie Strg + Shift + Leertaste (vorausgesetzt, alles ist ok eingerichtet) – Jonik

+0

Tatsächlich tut es. Wenn Sie während der Eingabe eines Bezeichners (z. B. eines Klassen- oder Methodennamens) die Tastenkombination Strg-Leertaste drücken, wird eine Liste aller möglichen Vervollständigungen einschließlich des API-Dokuments angezeigt. Und wenn Sie die STRG-Taste gedrückt halten und auf einen Bezeichner klicken, springt dieser zum Quellcode, in dem er definiert wurde. Diese Funktionalität ist auch über das Kontextmenü verfügbar. –

1

Dieses seltsame Verhalten:

Integer x; 
x = 12; 

Ist aufgrund java autoboxing.

Einige Geschichte:

Vor Java 1.5 es war nicht erlaubt.Sie hatten Primitive (int, char, byte, boolean, float, double,long) und der Rest in der Java-Welt waren Klassen (einschließlich der entsprechenden Wrapper: Integer, Character, Byte, Booelan, Float, Double, Long).

Die Kerndatenstrukturen von Java mit Objekten gearbeitet, also wenn Sie benötigten Zahlen in eine Liste zu speichern, man mußte „wrap“ Ihren Wert (die Wrapper nur reguläre Klassen sind, die eine primitive Art halten)

Für Beispiel kann dies mein eigener int Wrapper sein:

public class Entero { // integer in spanish... :P 
    private final int wrappedInt; 

    public Entero(int i) { 
     this.wrappedInt = i; 
    } 

    public int getEntero() { 
     return wrappedInt; 
    } 
} 

Nichts Besonderes, das ist ganz allgemein, wie die „Wrapper“ Klassen implementiert werden (natürlich gibt es dort viele Hilfsmethoden)

Also noch einmal, , ob Sie wollte es in einer Liste verwenden (die nur Objekte enthält) auf Sie haben:

List list = // get the list from somewhere.... 
list.add(new Integer(1024)); // wrap it 
.... 
// use the list and at some point iterate it: 
Iterator iterator = list.iterator(); 
while(iterator.hasNext()) { 
    Integer e = (Integer) iterator.next(); // unwrap it 
    i = e.intValue(); 
} 

list.add(1024) 

direkt nicht möglich war, Berufung, weil 1024 ein int wörtlichen ist, nicht ein Objekt.

Tonnen Code wurden so geschrieben, nach Jahren.

Seit Java 1.5 hinzugefügt Autoboxing, die im Grunde syntaktischer Zucker ist, jetzt "new Integer (i)/integer.intValue()" werden vom Compiler unter der Haube eingespritzt und der Code wurde:

list.add(1024); // wrapped in the compiled code in the the .class file that is. 
.... 
Iterator i = list.iterator(); 
while(i.hasNext()) { 
    int i = (Integer) i.next(); // unwrapped for you by the compiler under the hood 
} 

Entfernen der Wrapping-Prozess aus dem Quellcode.

Zusätzlich mit Generika, gespeichert Sie das Casting auch:

List<Integer> list = .... // <- you still have to say the list is of "Integers" not "int" 

.... 
Iterator<Integer> i = list.iterator(); // The iterator has to use the "<Integer>" generic mark 
while(i.hasNext()){ 
    int x = i.next(); // but you can get the value directly. 
} 

Grundsätzlich Generika eine Marke ist zu sagen, „überprüfen, was von dieser Art gewöhnt ist und stört mich nicht mit Casting mehr“, aber Generika sind ein anderes Thema.

Verwandte Themen