1. Alle klassen ervenObject
Alle klassen in Java erven de Object
klasse impliciet.
We analyseren wat overerving is en hoe het werkt in Java in de Java Core-zoektocht. Voor nu zullen we een eenvoudig feit beschouwen dat hieruit volgt:
Een object van elke klasse kan aan een Object
variabele worden toegewezen. Voorbeeld:
Code | Opmerking |
---|---|
|
De o variabele slaat een verwijzing naar een Scanner object op |
|
De o variabele slaat een verwijzing naar een String object op |
|
De o variabele slaat een verwijzing naar een Integer object op |
|
De o variabele slaat een verwijzing naar een String object op |
Dit is waar het goede nieuws eindigt. De compiler houdt het oorspronkelijke type object dat in een Object
variabele is opgeslagen niet bij, dus u kunt geen andere methoden op het opgeslagen object aanroepen dan de methoden van de Object
klasse.
Als u de methoden moet aanroepen die zijn gekoppeld aan het oorspronkelijke type van het object, moet u eerst een verwijzing ernaar opslaan in een variabele van het juiste type en vervolgens de methoden op die variabele aanroepen:
Code | Opmerking |
---|---|
|
Het programma zal niet compileren. De Object klasse heeft geen nextInt() methode. |
|
Dit zal werken. Hier slaan we een verwijzing naar een Scanner object op in een Scanner variabele met behulp van een typecast-operator . |
U kunt niet zomaar een variabele toewijzen Object
aan een scannervariabele, zelfs als de Object
variabele een referentie naar een Scanner
object opslaat. Maar u kunt dit doen als u de typecast-operator gebruikt , die u al kent. Dit is het algemene uiterlijk:
Type name1 = (Type) name2;
Waar name1
is de naam van een Type
variabele en name2
is de naam van een Object
variabele die een verwijzing naar een Type
object opslaat.
Typecasting
Als het type van de variabele en het type van het object niet overeenkomen, ClassCastException
wordt er een gegenereerd. Voorbeeld:
Code | Opmerking |
---|---|
|
Tijdens runtime treedt er een fout op: hier wordt een gegenereerd ClassCastException |
Er is een manier om deze fout in Java te voorkomen: we doen dit door het type object te controleren dat is opgeslagen in een variabele :
name instanceof Type
De instanceof
operator controleert of de name
variabele een Type
object is.
Laten we als voorbeeld een string zoeken in een reeks van verschillende objecten:
Code | Opmerking |
---|---|
|
Autoboxing converteert deze waarden naar respectievelijk een Integer , String en Double . Loop over de reeks objecten Als het object een is String Sla het op in een String variabele Toon de variabele op het scherm. |
2. Waarom generieke geneesmiddelen verschenen - collecties
Laten we terugkeren naar collecties.
Zodra Java-ontwikkelaars de ArrayList
klasse hadden gemaakt, wilden ze deze universeel maken, zodat er elk type object in kon worden opgeslagen. Dus gebruikten ze een reeks Object
s om de elementen op te slaan.
De kracht van deze aanpak is dat je een object van elk type aan de collectie kunt toevoegen.
Natuurlijk zijn er verschillende zwakke punten.
Nadeel 1.
Het was altijd nodig om een typeconversie-operator te schrijven bij het ophalen van elementen uit een verzameling:
Code | Opmerking |
---|---|
|
Maak een verzameling om verwijzingen naar Object objecten op te slaan Vul de verzameling met nummers 10 , 20 , ... 100 ; Tel de elementen van de collectie op Typecasting is noodzakelijk |
Nadeel 2.
Er was geen garantie dat een collectie een specifiek type element bevat
Code | Opmerking |
---|---|
|
Maak een verzameling om verwijzingen naar Object objecten op te slaan We vullen de verzameling met getallen die worden weergegeven als Double objecten: 0.0 , 2.5 , 5.0 , ... Som de elementen van de verzameling op Er treedt een fout op: a Double kan niet worden gecast naar eenInteger |
Gegevens kunnen overal in de verzameling worden geplaatst:
- op een andere manier
- in een ander programma
- uit een bestand
- via het netwerk
Nadeel 3.
De gegevens in de verzameling kunnen per ongeluk worden gewijzigd.
U kunt een verzameling gevuld met uw gegevens doorgeven aan een of andere methode. Die methode, geschreven door een andere programmeur, voegt zijn gegevens toe aan je verzameling.
De naam van de verzameling geeft niet duidelijk aan welke soorten gegevens erin kunnen worden opgeslagen. En zelfs als u uw variabele een duidelijke naam geeft, kan er een verwijzing naar worden doorgegeven aan een dozijn methoden, en die methoden zullen absoluut niets weten over de oorspronkelijke naam van de variabele.
3. Generieke geneesmiddelen
In Java worden al deze problemen geëlimineerd door dit coole ding dat generieke geneesmiddelen wordt genoemd.
In Java betekent generieke geneesmiddelen de mogelijkheid om typeparameters aan typen toe te voegen. Het resultaat is een complex samengesteld type. Het algemene beeld van zo'n samengesteld type is dit:
ClassName<TypeParameter>
Dit is een generieke klasse. En het kan overal worden gebruikt waar u normaal gesproken lessen gebruikt.
Code | Beschrijving |
---|---|
|
Variabelen maken |
|
Objecten maken |
|
Arrays maken |
Integer
In zo'n verzameling kunnen alleen variabelen worden opgeslagen:
Code | Beschrijving |
---|---|
|
ArrayList verzameling met Integer elementen Dit mag En dit gaat ook lukken
Autoboxen
Maar dit is niet toegestaan: compilatiefout |
Je leert hoe je je eigen klassen kunt maken met typeparameters in de Java Collections-zoektocht. Voor nu zullen we bekijken hoe ze te gebruiken en hoe ze werken.
4. Hoe generieke geneesmiddelen werken
Generieke geneesmiddelen zijn eigenlijk vreselijk primitief.
De compiler vervangt eenvoudig generieke typen door gewone typen. Maar wanneer methoden van een generiek type worden gebruikt, voegt de compiler een typecast-operator toe om parameters aan de typeparameters te casten:
Code | Wat de compiler doet |
---|---|
|
|
|
|
|
|
|
|
Stel dat we een methode hebben die de getallen in een verzameling gehele getallen optelt:
Code | Wat de compiler doet |
---|---|
|
|
Met andere woorden, generieke geneesmiddelen zijn een soort syntactische suiker, net als autoboxing, maar dan iets meer. Met autoboxing voegt de compiler methoden toe voor het converteren van an int
naar an Integer
en vice versa, en voor generieke versies voegt het typecast-operators toe.
Nadat de compiler uw generieke klassen met typeparameters heeft gecompileerd, worden ze eenvoudig geconverteerd naar gewone klassen en typecast-operators. Informatie over de type-argumenten die zijn doorgegeven aan variabelen van generieke typen gaat verloren. Dit effect wordt ook wel typeverwijdering genoemd .
Soms hebben programmeurs die generieke klassen schrijven (klassen met typeparameters) echt behoefte aan de informatie over de typen die als argumenten worden doorgegeven. In de Java Collections quest leer je hoe je hiermee om moet gaan en wat het inhoudt.
5. Een paar feiten over generieke geneesmiddelen
Hier zijn enkele meer interessante feiten over generieke geneesmiddelen.
Klassen kunnen verschillende typeparameters hebben. Het ziet er ongeveer zo uit:
ClassName<TypeParameter1, TypeParameter2, TypeParameter3>
Eigenlijk is dit niet echt verrassend. Overal waar de compiler een operator kan toevoegen om naar één type te casten, kan hij meerdere typecast-operators toevoegen.
Voorbeelden:
Code | Opmerking |
---|---|
|
De put eerste parameter van de methode is een Integer , en de tweede is eenString |
Generieke typen kunnen ook als parameters worden gebruikt . Het ziet er ongeveer zo uit:
ClassName<TypeParameter<TypeParameterParameter>>
Stel dat we een lijst willen maken waarin lijsten met tekenreeksen worden opgeslagen. In dit geval krijgen we zoiets als dit:
// List of greetings
ArrayList<String> listHello = new ArrayList<String>();
listHello.add ("Hello");
listHello.add ("Hi");
// List of goodbyes
ArrayList<String> listBye = new ArrayList<String>();
listBye.add("Bye");
listBye.add ("Goodbye");
// List of lists
ArrayList<ArrayList<String>> lists = new ArrayList<ArrayList<String>>();
lists.add(listHello);
lists.add(listBye);
Generieke typen (typen met typeparameters) kunnen ook als arraytypen worden gebruikt. Het ziet er ongeveer zo uit:
ClassName<TypeParameter>[] array = new ClassName<TypeParameter>[size];
Er gebeurt hier niets magisch: de punthaken geven alleen de typenaam aan:
Code | Niet-generieke tegenhanger |
---|---|
|
|
|
|
|
|
GO TO FULL VERSION