Hvad er generiske stoffer i Java
En generisk klasse er en speciel klasse, der genererer en eller flere ikke-specifikke java-typer ved instansiering. Dette hjælper med at fjerne runtime-undtagelsesrisikoen "ClassCastException", når vi skal caste mellem forskellige typer. Med disse generiske klasser har man mulighed for at oprette klasser, der fungerer med forskellige java-datatyper. Generiske stoffer hjælper med at forbedre kodens kvalitet og effektivitet.
Hvad mener jeg, når jeg siger "fjern risikoen for runtime-undtagelse (ClassCastException)"? okay, lad os få en bedre forståelse ved at bruge eksempler:
Typecasting skaber ClassCastException
package generics; import java.util.ArrayList; import java.util.List; public class Generics { public static void main(String[] args) { List arraylist = new ArrayList(); arraylist.add("xyz"); arraylist.add(new Integer(5)); for(Object obj : arraylist){ String s=(String) obj; } } }
Output:
run:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at generics.Generics.main(Generics.java:16)
C:\Users\Mozerian\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 1 second)
I ovenstående kode skriver vi casted String s=(String) obj som fører til ClassCastException under kørsel. Denne runtime fejl skyldes, at det objekt, vi sender på listen, er en streng, hvor vi erklærede et af vores elementer som en heltalstype.
Ingen type casting fjerner ClassCastException
package generics; import java.util.ArrayList; import java.util.List; public class Generics { public static void main(String[] args) { List<String> arraylist = new ArrayList<String>(); arraylist.add("xyz"); //compiler error for(String s : arraylist){ } } }
Output:
run:
BUILD SUCCESSFUL (total time: 0 seconds)
Hvis vi fjerner String s=(String) obj så fjerner vi ClassCastException under kørsel. Et punkt at bemærke, også hvis vi tilføjer list1.add(new Integer(5)) vi får igen en kompileringsfejl.
Fordele ved at bruge Generics
Lad os nu grave dybere ned ved at se på fordelene ved at bruge generiske lægemidler.
Kodegenanvendelighed
Generiske tillader genbrug af kode, det betyder, at vi kan skrive en grænseflade/klasse/metode og bruge den til enhver type
package generics; import java.util.ArrayList; import java.util.List; public class Generics { public static void main(String[] args) { Generics generic = new Generics(); System.out.println("===printing the integer values=="); generic.showData(1,2 ); System.out.println("===printing the string values==="); generic.showData("Generics in", "Java is good"); } public <T> void showData(T x, T y) { System.out.println(x); System.out.println(y); } }
Output:
run:
===printing the integer values==
1
2
===printing the string values===
Generics in
Java is good
BUILD SUCCESSFUL (total time: 1 second)
I ovenstående kode er der ingen steder, vi har erklæret heltal eller streng, men ved at bruge generisk kan vi genbruge koden til at udskrive enhver type, vi ønsker. Vi kan også udskrive float-type blot ved at tilføje generic.showData(1.212, 2.234);
Kompileringstypesikkerhed
Generics hjælper kodesikkerheden, da det giver dig mulighed for at kende en kodefejl på kompileringstidspunktet snarere end ved kørselstiden. Ved at bruge generiske artikler vil compileren vise en fejl på kompileringstidspunktet snarere end ved runtime. Hvordan hjælper dette? som programmør tror jeg, du ved, hvor svært det kan være at finde en fejl under kørslen, men det er ligetil at finde en fejl på kompileringstidspunktet, da redaktøren selv klager.
Fjerner individuel type støbning
Ved brug af generiske stoffer kræver vi ikke individuel støbning.
Lad os tage et kig på et eksempel:
I nedenstående kode kræver kode A typecasting, da vi ikke har brugt generika. Når vi først har introduceret generiske stoffer i koden, behøver vi ikke at skrive cast.
package generics; import java.util.ArrayList; import java.util.List; public class Generics { public static void main(String[] args) { List arraylist = new ArrayList(); arraylist.add("here we need type casting"); String typecast = (String) arraylist.get(0); List<String> list = new ArrayList<String>(); list.add("here we do not need type casting"); String notypecast = list.get(0); } }
Sidst men ikke listen er generiske stoffer, der hjælper med at implementere ikke-generiske algoritmer.
Generisk objektinitialisering
Et generisk objekt kan indeholde data af én type eller flere. For at initialisere objekt med én type.
Generic <String> gen = new Generic <String>();
For at initialisere objekt af to typer:
Generic <String,Interger> gen = new Generic <String,Integer>();
Dette fortæller klassen, at type 1-objektet er en streng, og type 2-objektet er et heltal. Fordelen ved dette i en generisk klasse er objekter af typen eksempel med forskellige typer givet for hver, så du kan initialisere et andet objekteksempel med
Generiske typer
Generisk klasse
En generisk klasse er en klasse, der kan henvise til enhver datatype. Derfor definerer du typen under instansieringen.
Generiske typer erklæres ved hjælp af vinkelparenteserne <> omkring en parameterholdertype f.eks.
Lad os konvertere en normal java-klasse til en generisk klasse:
Normal klasse
public class Generics { private String name; public void set (String setname) { name = setname; } public String get() { return name; }
I ovenstående eksempel har vi erklæret en klasse, så gik vi videre og erklærede en strengvariabel navn der indeholder strengdatatypen. Vi brugte derefter setter-metoden til at sætte navnet til et nyt navn og bruge getter-metoden til at returnere det. I driverklassen, hvis vi sender en streng i set-metoden og prøver at caste den som int, vil vi modtage en casting-fejl ved kørsel. Strengen kan ikke konverteres til int.
public static void main(String[] args) { Generics cars = new Generics(); cars.set(T) Int number = (int)cars.get(); System.out.println(number); } }
Antag, at vi ikke ønsker at beskæftige os med strengdatatype i dette tilfælde, bliver vi nødt til at ændre datatypen ved deklaration. Men dette kan opnås meget nemt ved hjælp af en generisk klasse, hvor vi kan bestemme den datatype, vi ønsker ved instansiering.
Generisk klasse
public class Generics<T> { private T t; public void set (T setname) { t = setname; } public T get() { return t; }
Generisk driverklasse
public static void main(String[] args) { Generics <Integer> IntValue = new Generics <Integer> (); Generics <String> StringValue = new Generics <String>(); IntValue.set(T); StringValue.set("Test"); int nunmber = IntValue.get(); String st = StringValue.get(); }
Generiske metoder
Indtil videre har vi lavet generiske klasser, men vi kan også lave generiske metoder uden for en generisk klasse. Ligesom typedeklaration er metodedeklaration generisk. En eller flere typer parametre parametrerer det. Generiske metoder er metoder, der kan acceptere enhver form for argument. Det tillader kun både statiske og ikke-statiske metoder, at rækkevidden af argumenterne er begrænset til den metode, hvor den er erklæret.
Vi vil bruge en type interface diamant til at skabe generiske metoder.
Grænsefladediamanten
En type interface-diamant giver dig mulighed for at oprette en generisk metode, som du ville gøre med en almindelig metode, uden at angive en type mellem vinkelparenteser.
Men hvorfor en diamant?
Vinkelbeslagene omtales ofte som diamant <>
Typisk, hvis der kun er én type inde i diamanten, bruger vi
package generics; import java.util.ArrayList; import java.util.List; public class Generics<T> { public static <K> void printArray(K [] arrayElements){ for(K elements :arrayElements){ System.out.println(elements ); } System.out.println(); } public static void main(String[] args) { Integer [] arrayInt = {1,2,3,4,5}; String [] arrayString = {"moses","njorge"}; Character[] arrayChar = { 'A', 'V', 'C', 'D'}; System.out.println( "Printing Integer Array" ); printArray( arrayInt ); System.out.println( "Printing String Array" ); printArray( arrayString ); System.out.println( "Printing Char Array" ); printArray( arrayChar ); } }
Output:
run:
===Printing Integer Array===
1
2
3
4
5
==Printing String Array===
Generics
in java is Sweet
===Printing Char Array==
A
B
B
A
BUILD SUCCESSFUL (total time: 1 second)
I ovenstående kode definerede vi en generisk metode printArray for at returnere indholdet af arrayet. Driver-calss i hovedmetoden tillader flere array-typer.
Generisk grænseflade
En grænseflade er en java-konstruktion, der hjælper med at definere de roller, som et objekt kan påtage sig. Vi kan også oprette en generisk grænseflade.
package java.lang; import java.util.*; Public interface School <T1,T2>{ public int School(T1 t); public String School(T2 p); }
En grænseflade er implementeret af en klasse og udvidet med en anden grænseflade. Lad os implementere grænsefladen ovenfor.
Public class Faculty implements School<Integer,String>{ Public Integer School (Integer t) { //execution code } Public String School (String p) { //execution code } }
Generisk konstruktør
En konstruktør er en speciel type metode, der bruges til at initialisere et objekt eller kan påberåbes, når et objekt af den pågældende klasse oprettes. Lad os tage et kig på et eksempel på en generisk konstruktør
public class Cars<T> { private T toyota; private T isuzu; private T mercedes; public Cars(T toyota, T isuzu, T mercedes) { super(); this.toyota = toyota; this.isuzu = isuzu; this.mercedes = mercedes; }
I dette eksempel har bilklassens konstruktør typeoplysningerne. Derfor kan du kun have en forekomst af biler med alle attributter af en enkelt type.
Skriv parameternavn
For at skelne de generiske typeparameternavne fra java-variabler, laves navnene enkelt, store bogstaver. Dette danner deres egen navnekonvention. Disse parametre omfatter.
T-type
E-element (bruges i vid udstrækning af java-samlingsrammerne)
N-nummer
K-tast (bruges i kort)
V-værdi (bruges på kort)
S,U,V osv- 2
nd
,3
rd
,4
th
typer.
Generiske WildCards.
I java præsenterer vi jokertegn ved hjælp af et spørgsmålstegn (?). De henviser til en ukendt type. Jokertegn med generisk giver os mulighed for at skabe kontrol over den type, vi bruger. Vi kan ikke bruge et jokertegn, mens vi instansierer en generisk klasse eller påberåber os en generisk metode.
De falder i to kategorier
Afgrænset
De bundne typer bruges, når vi ønsker at begrænse variabeltyperne i en metode. De er af to typer.
. udvider type>
For at erklære denne type grænse starter du med at angive typeparameternavnet, efterfulgt af udvide nøgleordet og til sidst øvre grænse.
public static <T extends Comp<T>> int compa(T t1, T t2){ return t1.compareTo(t2); }
.
Lad os tage et eksempel, vi ønsker at tilføje tegn/heltal til en liste over tegn/heltal i en metode, super Søgeord bruges sammen med en nedre grænse.
public static void IntegersAdd(List<? super Integer> list){ list.add(new Integer(50)); }
Ubegrænset
>betegner et ubegrænset jokertegn
Vi bruger ubundet type, når vi ønsker, at den generiske metode skal fungere med alle datatyper,
Eksempel:arrayList >(rep. arrayList af ukendt type)
public static void print(List<?> list){ for(Object data : list){ System.out.print(data + "::"); } }
Punkter at bemærke, når du arbejder med generiske typer
Mens du arbejder med generiske typer, husk følgende:
- Typerne skal identificeres ved instansieringen af klassen
- Din klasse skal indeholde metoder, der indstiller typerne inde i klassen til den type, der sendes ind i klassen ved oprettelse af et objekt i klassen
- En måde at se på den generiske klasse er ved at forstå, hvad der sker bag koden.
Don'ts i Java Generics
Opret ikke statiske felter af typen, dette vil generere en kompileringstidsfejl.
public class Generics<T> { private static T name; }
Opret ikke forekomster af T. Dette vil føre til en fejl.
public class Generics<T> { public Generics(){ new T(); } }
Opret ikke en generisk undtagelsesklasse. Dette forårsager kompileringsfejl.
public class Generic<T> extends Exception {}
Opret ikke generiske stoffer med primitiver-deklaration.
final List<int> AddList = new ArrayList<>();
Konklusion
I denne tutorial har vi diskuteret generiske stoffer i java; vi har dækket generisk klasse, grænseflade, konstruktør og metoder. Vi gik videre og kiggede på de generiske wildcards og parametre og til sidst på don'ts i generiske. Med det diskuteret, er det tydeligt, at generisk er blevet en god funktion, som alle programmører bør sætte pris på, da programmørernes liv med brugen af generiske lægemidler er gjort lettere.