Heim  >  Artikel  >  Java  >  Häufige Missverständnisse und Details zu Java

Häufige Missverständnisse und Details zu Java

黄舟
黄舟Original
2017-02-06 15:56:011199Durchsuche

Ich habe ein Buch namens „Java In-Depth Analysis“ gefunden, das viele Missverständnisse beinhaltet, auf die ich normalerweise nicht achte. Es darf während der Entwicklung nicht verwendet werden, aber diese Konzepte sollten nicht vage sein. Der Inhalt des Buches ist immer noch sehr nützlich. Hier einige zusammenfassende Anmerkungen.

Häufige Missverständnisse und Details zu Java

1. In Java gibt es keine goto-Anweisung. Da die häufige Verwendung von goto-Anweisungen die Lesbarkeit und Wartbarkeit des Programms beeinträchtigt, wurde die Verwendung von goto in der Java-Sprache abgeschafft. Um gleichzeitig die Verwirrung zu vermeiden, die durch die Verwendung von goto durch Programmierer verursacht wird, definiert die Java-Sprache goto immer noch als Schlüsselwort, definiert jedoch keine Syntax und wird daher als „reserviertes Wort“ bezeichnet.

2, true, false und null werden in der IDE in verschiedenen Farben angezeigt, es handelt sich jedoch nicht um Schlüsselwörter, sondern um „literale Konstanten“, genau wie abc vom Typ String.

3. Vermeiden Sie die Verwendung von $ beim Definieren von Namen, da der Compiler beim Kompilieren der .java-Datei „$“ in einen Connector zwischen dem oberen Typ und dem unteren Typ kompiliert. Siehe das folgende Beispiel:

package com.laixintao.Test;   

public class Outer$Inner {   
    public static void main(String[] args) {   
        Outer o = new Outer();   
        Outer.Inner i = o.new Inner();   
        i.innerPrint();   
    }   
}   

class Outer {   
    class Inner {   
        void innerPrint() {   
            System.out.println("Inner Print!");   
        }   
    }   
}

Beim Kompilieren (javac Test3.java) dieses Codes meldet der Compiler den folgenden Fehler: Test.java:12: Fehler: Doppelte Klasse: com.laixintao.Test . Outer.Inner-Klasse Inner{ ^

4. Unicode-Escape-Zeichen werden sehr früh verarbeitet, vor dem Parsing-Programm. Beispiel:

// char c1 = 'u00a';   
// char c2 = 'u00d';

Wenn diese beiden Codezeilen im Programm erscheinen, wird ein Kompilierungsfehler gemeldet. Diese beiden Unicode-Codes stellen „Zeilenvorschub“ bzw. „Wagenrücklauf“ dar. Wenn der Compiler also kompiliert, sieht der Code wie folgt aus:

// char c1 = '   
';   
// char c2 = '   
';

5. Unicode-Code verwendet 16-Bit-Zeichenkodierung wird in Java durch den Typ char dargestellt. Jetzt wurde Unicode auf eine Million Zeichen erweitert, und diejenigen, die die 16-Bit-Grenze überschreiten, werden zu zusätzlichen Zeichen. Alle Zusatzzeichen können nicht durch Zeichenkonstanten dargestellt werden.

6. Wenn short, byte und char an der Operation beteiligt sind, ist das Ergebnis vom Typ int und nicht mit dem höheren Typ identisch. Wenn eine Variable vom Typ Byte, Short oder Byte ist und ihr eine Konstante zur Kompilierungszeit zugewiesen ist und die Konstante den Wertebereich der Variablen nicht überschreitet, kann der Compiler eine implizite Kontraktionskonvertierung durchführen. Diese implizite Schrumpfungskonvertierung ist sicher, da sie nur für Variablenzuweisungen und nicht für Methodenaufrufanweisungen gilt, d. h. sie gilt nicht für die Parameterübergabe beim Aufrufen von Methoden. (Einzelheiten finden Sie unter „Kleinere Probleme bei der Standardtypkonvertierung in Java“)

7. Achten Sie auf den Typ char, der ein vorzeichenloser Typ ist. Daher muss bei der Konvertierung zwischen char und short oder char und byte explizit die Typkonvertierung verwendet werden. Die Konvertierung von Byte in char ist eine Erweiterungs- und Kontraktionskonvertierung. Diese Konvertierung ist etwas ganz Besonderes, das heißt, das Byte wird zuerst erweitert und in int konvertiert und dann in char kontrahiert.

8. Bei der Erweiterungskonvertierung zwischen Ganzzahldaten wird eine vorzeichenlose Erweiterung durchgeführt, wenn der Operand vom Typ char (Typ ohne Vorzeichen) ist. Wenn der Operand vom Typ Byte, Short oder Int (mit Vorzeichen) ist Typ), wird eine Vorzeichenerweiterung durchgeführt, und das Erweiterungsbit ist das Vorzeichenbit der Variablen.

9. Bei der Kontraktionskonvertierung zwischen ganzzahligen Daten werden nur die hohen Bits abgeschnitten und verworfen, ohne dass eine weitere Verarbeitung erfolgt.

10. 0,1+0,2 ist nicht gleich 0,3.System.out.println((double)0,1+(double)0,2); Das Ausgabeergebnis dieser Anweisung ist 0,3000000000000004. Da Computer zum Speichern von Daten Binärzahlen verwenden, können viele Dezimalzahlen nicht genau mit Binärzahlen dargestellt werden (tatsächlich sind die meisten Dezimalzahlen Näherungswerte), ebenso wie die Verwendung von Dezimalzahlen Brüche wie 1/3 nicht genau darstellen kann. Die meisten Gleitkommatypen speichern ihre Werte nur annähernd im Computer, nicht so genau wie Ganzzahlen. Ein weiteres Beispiel ist eine Endlosschleife: for(float f = 10.1f;f != 11;f+=0.1f){}

11 Der Float-Typ kann 7 bis 8 signifikante Ziffern behalten, während der double Der Typ kann 15 bis 16 signifikante Ziffern behalten. Wenn der Wert vom Typ int oder long mehr signifikante Ziffern als Double oder Float hat, gehen einige der niedrigstwertigen Bits des Werts verloren, was zu einem Genauigkeitsverlust führt Zu diesem Zeitpunkt extrahiert der IEEE754-Modus für die nächste Rundung den Gleitkommawert, der dem ganzzahligen Wert am nächsten kommt. Obwohl es sich bei der Konvertierung von Ganzzahlen in Gleitkomma um eine erweiterte Konvertierung handelt, kommt es zu einem gewissen Präzisionsverlust, wenn der numerische Wert sehr groß oder sehr klein ist (der Absolutwert ist sehr groß).

12. Wie berechnet man i+++j? (Dieses Problem wird in C/C++ diskutiert) macht wenig Sinn, da C/C++ von der Hardwarestruktur der Implementierung abhängt und die Ergebnisse in verschiedenen Umgebungen unterschiedlich sind. In Java ist dieses Ergebnis jedoch fest und wird nicht von der Hardwareumgebung und der Plattform beeinflusst, auf der es ausgeführt wird.) Antwort: Gemäß der Greedy-Regel ist Präfix ++ besser als Postfix ++, und das Ergebnis ist (i++) + j

13. i++ und ++i addieren tatsächlich zuerst +1 und weisen dann den Wert zu. ++i, es gibt nichts zu sagen; i++, die zugrunde liegende Implementierung ist: temp = i;i = i + 1; j = temp; i++; Das Ergebnis ist 15. (Da eine Zuweisung durchgeführt wird, nachdem eins hinzugefügt wurde, wechselt es von 16 zurück zu 15)

14 Die Vorzeichenbits von +0 und -0 im Gleitkomma-Variablenspeicher sind unterschiedlich . Wenn -0 und +0 an Operationen im Zusammenhang mit Gleitkommatypen beteiligt sind (z. B. Divisions- und Restoperationen), können unterschiedliche Ergebnisse erzielt werden.

15. Die Divisions- und Restoperationen von Gleitkommazahlen unterscheiden sich von den Divisions- und Restoperationen von Ganzzahlen. Wenn der Divisor 0 ist, erzeugen Gleitkommaoperationen keine ArithmeticException.

16. Die String-Klasse ist eine nicht veränderliche Klasse. Sobald ihr Objekt erstellt wurde, kann es nicht zerstört werden. Die Methoden der String-Klasse, die scheinbar Zeichenfolgen ändern, geben tatsächlich neu erstellte String-Objekte zurück, anstatt das Objekt selbst zu ändern.

17. Da das String-Objekt unveränderlich ist, ist es threadsicher und kann frei geteilt werden.

18 Innerhalb der String-Klasse wird ein Zeichenarray (char[]) verwendet, um die Zeichenfolge beizubehalten. Die maximale Länge von String ist die maximale Länge des Zeichenarrays. Theoretisch ist die maximale Länge der Maximalwert des int-Typs, der 2147483647 beträgt. In der Praxis ist der maximal erreichbare Wert im Allgemeinen kleiner als der theoretische Maximalwert .

19. Die main()-Methode ist hinsichtlich des Leistungsverhaltens im Grunde das gleiche wie andere Methoden. Sie kann überladen, von anderen Methoden aufgerufen, geerbt und ausgeblendet werden und kann auch Ausnahmen mit Typparametern auslösen. Wir können die Hauptmethode (oder andere Methoden) auch durch Reflektion in einem Programm aufrufen.

20. Wenn zwei oder mehr Methoden denselben Namen, aber unterschiedliche Parameterlisten haben, stellen diese Methoden eine Überladung dar. Überladene Methoden können anhand des der Parameterliste entsprechenden Typs und der Anzahl der Parameter unterschieden werden. Der Name des Parameters, der Rückgabetyp der Methode, die Ausnahmeliste der Methode und die Typparameter können jedoch nicht verwendet werden Bedingungen zur Unterscheidung überladener Methoden.

21. Welche Methode aufgerufen werden soll, die Reihenfolge ist wie folgt:

In der ersten Stufe werden automatisches Boxen (Unboxing) und variable Parameter nicht berücksichtigt und der entsprechende formale Parametertyp wird gesucht Methoden, die mit dem tatsächlichen Parametertyp übereinstimmen können, und die Anzahl der formalen Parameter ist dieselbe wie die Anzahl der tatsächlichen Parameter.

Wenn in Schritt eins keine qualifizierte Methode vorhanden ist, erfolgt in der zweiten Phase das automatische Ein- und Auspacken ausgeführt werden.

Wenn in Schritt 2 keine qualifizierte Methode vorhanden ist, wird in der dritten Stufe die Methode mit variablen Parametern berücksichtigt.

Wenn in den drei Phasen keine qualifizierte Methode gefunden wird, tritt ein Kompilierungsfehler auf. Wenn es mehr als eine Möglichkeit zur Konditionierung gibt, wird die spezifischste Methode ausgewählt. Die klarste Methodendefinition lautet: Wenn der entsprechende formale Parameterlistentyp von Methode A dem formalen Parameterlistentyp von Methode B zugeordnet werden kann, dann ist Methode A klarer als Methode B. Wenn die eindeutigste Methode nicht ausgewählt werden kann, kommt es zu einem Kompilierungsfehler.


22 Der wesentliche Unterschied zwischen Umschreiben und Ausblenden besteht darin, dass das Umschreiben dynamisch gebunden ist und die Methode zum Aufrufen verwandter Klassen basierend auf dem tatsächlichen Typ des Objekts bestimmt wird, auf das verwiesen wird durch die Laufzeitreferenz. Hidden ist statisch gebunden und die relevanten aufzurufenden Mitglieder werden basierend auf dem statischen Typ bestimmt, auf den zur Kompilierungszeit verwiesen wird. Mit anderen Worten: Wenn eine Unterklasse die Methode einer übergeordneten Klasse überschreibt und die Referenz der übergeordneten Klasse auf das Objekt der Unterklasse zeigt, wird die Methode der Unterklasse über die Referenz der übergeordneten Klasse aufgerufen. Wenn eine Unterklasse eine Methode (Mitgliedsvariable) der übergeordneten Klasse verbirgt, wird die Methode (Mitgliedsvariable) der übergeordneten Klasse weiterhin über einen Verweis auf die übergeordnete Klasse aufgerufen.

23. Der Konstruktor der Unterklasse ruft den Konstruktor der übergeordneten Klasse auf, bis der Konstruktor der Objektklasse aufgerufen wird.

24 Der Konstruktor erstellt kein Objekt. Der Konstruktor wird vom System aufgerufen, wenn new zum Erstellen eines Objekts verwendet wird, und wird zum Initialisieren von Instanzmitgliedern der Klasse verwendet. In Bezug auf die Reihenfolge wird zuerst das Objekt erstellt und dann der Konstruktor aufgerufen. (Der Konstruktor generiert kein neues Objekt)

25. Der Standardkonstruktor ist nicht leer. Dieser Konstruktor ruft den parameterlosen Konstruktor der übergeordneten Klasse auf und führt möglicherweise die Initialisierung von Instanzmitgliedsvariablen durch. Daher ruft der Standardkonstruktor zumindest den Konstruktor der übergeordneten Klasse auf und erledigt möglicherweise mehr Arbeit, einschließlich der Initialisierung der Instanzvariablendeklaration und des Instanzinitialisierungsblocks, die alle im Konstruktor ausgeführt werden.

26 Wenn einer der beiden Operanden des Operators == oder != ein Basisdatentyp und der andere ein Referenztyp der Wrapper-Klasse ist, entpacken Sie den Referenztyp und konvertieren Sie ihn in den Basisdatentyp dann vergleichen Ob die Werte der beiden Basisdatentypen gleich sind.

27. In Java sind Arrays auch Klassen, und die im Array deklarierten Referenzvariablen verweisen auf Objekte des Array-Typs. Alle Arrays erben die Object-Klasse und implementieren die Schnittstellen java.lang.Cloneable und java.io.Serializable. Zu den Mitgliedern des Arrays gehören die variable Länge (die implizit vorhanden ist) und von der Object-Klasse geerbte Mitglieder. Cloneable und Serializable sind zwei markierte Schnittstellen, die keine Mitglieder explizit deklarieren.

28. Die Schnittstelle ist ein völlig abstraktes Design und kann nicht instanziiert werden. Durch die Verwendung des von A mit der neuen Methode erstellten Excuse-Typs wird tatsächlich eine anonyme Klasse erstellt, die den Schnittstellentyp implementiert.

29. Wenn zwei Schnittstellen dieselbe Variable x deklarieren, tritt beim einfachen Namenszugriff ein Kompilierungsfehler auf, wenn eine Schnittstelle beide Schnittstellen gleichzeitig erbt oder eine Klasse beide Schnittstellen gleichzeitig implementiert.

30. Wenn zwei Schnittstellen Methoden mit demselben Namen deklarieren und die beiden Methoden keine Überladung darstellen, dann kann eine Schnittstelle beide Schnittstellen gleichzeitig erben oder eine Klasse kann beide Schnittstellen erben muss eine Methodensignatur sein, sodass die Signatur gleichzeitig eine Untersignatur von zwei m Methodensignaturen ist, und im Rückgabetyp der Methode muss ein Typ vorhanden sein, sodass der Typ der Rückgabetyp beider m Methoden ist zugleich austauschbarer Typ.

Die oben genannten sind die häufigsten Missverständnisse und Details zu Java. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn