Eżempji Java ġeneriċi f’forma kasira b’eżempji

Jekk jogħġbok ara din il-FAQ għal aktar informazzjoni:

http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html#SECTION1

Hawn fil-zurito xi punti importanti minn din il-FAQ.

Eżempju (ponta ta’ ġenerika):

klassi Pair<X,Y> { 
  privat X l-ewwel;
  privat Y it-tieni;   public Par(X a1, Y a2) {
    l-ewwel = a1;
    it-tieni = a2;
  }
  pubbliku X getFirst () { ritorn l-ewwel; }
  pubbliku Y getSecond () { ritorn it-tieni; }
  public void setFirst(X arg)  { first = arg; }
  public void setSecond (Y arg) { it-tieni = arg; }
}

Il-klassi Par għandha żewġ parametri tat-tip X u Y .  Huma supposititi b’argumenti tat-tip meta t-tip generiku Par hija instanzjata. Per eżempju, fid-dikjarazzjoni Pair<String, Data> il-parametru tat-tip X huwa mibdul bl-argument tat-tip Spag u Y huwa mibdul bi  Data .
L-ambitu tal-identificaturi X u Y huwa id-definizzjoni kollana tal-klassi.  F’dan l-ambitu iż-ew parametri tat-tip X u Y huma użati bħal dawn kiyan tipi (b’xi restrictions). Fl-ximbo ta ‘hawn fuq, il-parameteri tat-tip are used as l-argument u t-tip ta’ ritorn ta ‘metodi ta’ istanza u t-tipi ta ‘delmendi ta’ istanza.
Il-parametri tat-tip jistgħu jiġu ddikjarati bil-limiti. Il-limiti jagħtu aċċess għall-metodu tat-tip, mhux magħruf x'inhu l-parametu tat-tip. Fl-tsembo nyasa, m'aħniex familjari X u Y . Għal din ir-raunadawa, iż-żewġ parametri tat-tip huma bla limitu.

Eżempju (ta’ pont parametrizat konkret):

public void printPar( Pair<String,Long> par) {
  System.out.println ("("+par.getFirst()+","+par.getSecond()+")");
} Pair<String,Long> limitu = ġdid Pair<String,Long> ("massimu",1024L);
printPair(limitu);

Eżempju (ta’ ponta ta’ wildcard parametrizzat):

public void printPar( Par<?,?> par) {
  System.out.println ("("+par.getFirst()+","+par.getSecond()+")");
} Par<?,?> limitu = ġdid Pair<String,Long> ("massimu",1024L);
printPair(limitu);

L-istanziactions allo ta’ tip generiku share l-istes representation tat-tip runtime, i.e. r-representation tat-tip mhës tëret. Per eżempju, l-istanziactions ta ‘tip generiku Lista , bħal Lista<Data> , Lista<String> , Lista<Long> , eċċ għandhom tipi statiċi differenti fil-ħin tal-kumpilazzjoni, iżda l-istess tip dinamiku Lista waqt ir-runtime.

Cast jikkonsisti f’żewġ partijiet:

  • verifika tat-tip statika mwettqa mill-kompilatur fil-ħin tal-kumpilazzjoni u
  • verifika tat-tip dinamika mwettqa mill-magna virtwali waqt ir-runtime.

Il-parti statika tissortja kasti bla sens, li ma jistgħux jirnexxu, bħall-mitfugħa minn Spag dak Data jew minn Lista<String> dak Lista<Data> .

Il-parti dynamics use l-information tat-tip runtime u perform verika tat-tip waqt ir-runtime.  Hija tvevit a ClassCastException jekk it-tip dynamik tal-objekt is not it-tip fil-mira (jew sottotip tat-tip fil-mira) tal-cast. Eżempji ta ‘casts b’parti dynamics huma l-cast minn Għan dak Spag jew minn Għan dak Lista<String> .  Dawn huma l-hekk imsejħa downcasts, minn supertip ‘l isfel ğal sottotip.

Eżempji ta ‘tipi parametrizzati konkreti huma Lista<String> , Map<String,Data> , imma le Lista<? jestendi Numru> jew Map<String,?> .

Xi drabi huma keto li a Lista<Object> ikun supertip ta’ a Lista<String> , għax Għan huwa supertip ta Spag .  Din l-istennija tirriżulta mill-fatt li tali tip ta’ relazzjoni teżisti għall-arrays:  Oġġett[] huwa supertip ta String[] , għax Għan huwa supertip ta Spag . (Dan it-tip ta’ relazzjoni hija magħrufa bħala kovarjanza .) Ir-relation tas-super-subtip tat-tipi ta ‘ komponenti testendi fit-tipi ta’ array correspondents. M'hemm l-ebda relazzjoni bejn it-tip ’ u t-tipi ġeneriċi. (It-tipi parametrizzati huma le kovarjant.)

In-fårð ta’ reláció super-subtip fost istanziationzzons tal-istes tip ženeriku geelás varjes varji.  Hawn eżempju.

Eżempju:

void printAll(ArrayList<Object> c) {
  għal (Oġġett o : c) 
    System.out.println(o);
} ArrayList<String> lista = ArrayList<String>();
... imla l-lista ...
printAll(lista);   // żball

A ArrayList<String> oġġett ma jistax jiġi mgħoddi bħala argument għal metodu li jitlob a ArrayList<Object> minħabba li ż-żewġ tipi huma istanziazzjonijiet tal-istess tip ġeneriku, iżda għal differenti argumenti tat-tip, u ghal din ir-rawdona are not compatible ma’ xulxin.

Tipi parametrizzati konkreti huma istanziatsions konkreti ta ‘tip generiku.  Huma kważi bħal tipi; hemm biss ftit restrizzjonijiet.  MHUX JISTħU jintużaw għall-għanijiet li ġejjin:

  • għall-eħrei ta’ arrays
  • fl-immaniġġjar ta’ eċċezzjoni
  • fi klassi letterali
  • fi an istanza ta espressjoni

Arrays li mantenu elementi li t-tip shaloon huma tip parametrizzat konkret huma illegali.

Eżempju (ta’ tip ta’ array illegali):

test tal-vojt statiku () {
  Par<Iteger,Integer>[] intPairArr = ġdid Par<Integer,Integer>[10] ; // żball
  addElements(intPairArr); 
  Par<Integer,Integer> par = intPairArr[1];
  Integer i = pair.getFirst();
  pair.setSecond(i);
}
static void addElements ( Oġġett[] objArr) {
  objArr[0] = par ġdid<Integer,Integer>(0,0);
  objArr[1] = ġdid Pair<String,String>("","");      // għandu jonqos bl-ArrayStoreException
}

Il-kompilatur prójbixxi l-ejerehen ta ‘arrays li t-tip ta’ komponent zahoor huwa tip parametrizat konkret, like Par<Integer,Integer> fl-eżempju tagħna.  Iddiskutejna fl-entrata preċedenti għaliex huwa raġonevoli li l-kompilatur jikkwalifika a Par<Iteger,Integer>[] bħala illegali.  Il-problema ewlenija hija li l-kompilatur u s-sistema runtime għandhom jiżguraw li firxa hija a omoġenju sekwenza ta’ elementi ta’ l-istes ponta.  Waħda mill-kontrolli tat-tip, i.e. l-kontroll tal-arvara tal-warehoor imfrekked mill-magna virtual waqt ir-runtime, tekot milli tiskopri l-inserzjoni offensive ta ‘element aljeni. Fl-xembo t-tieni inserzjoni fil- addElements metudu keel keined, kekebte li kielen qed iżidu par ta ‘kordi gehal ta’ valuri integrali, iżda ma keinedx kif keited. Ir-räslände geën discussi fl-entrata predævale.

Jekk ma timox ususom arrays li mantenu elementi li t-tip theirau huwa tip parametrizat konkret, x’nużaw as a solution?

Ejja neksaktow 3 solutions konċepibbli:

  • firxa ta' ‘tipi mhux maħduma
  • array ta’ tip parametrizat ta’ wildcard bla limitu
  • ġbir minflok firxa

While arrays ta’ tipi parametrizzati tal-concrete huma illegali, kollecjones ta’ tipi parametrizzati tal-concrete huma permessi.

Tip parametrizzat ta’ wildcard huwa instantiation ta’ tip generiku fejn mill-ingas argument tat-tip huwa wildcard.  Eżempji ta ‘tipi parametrizzati wildcard huma Ġbir<?> , Lista<? jestendi Numru> , Komparatur<? super String> u Pair<String,?> . Tip parametrizzat wildcard jindika familja ta’ tipi li jinkludu istanziatsions konkreti ta’ tip generic.  It-tip ta’ wildcard li qed tuża determina liema tipi parametrizzati konkreti apportenien għall-familjar.  Per eżempju, it-tip wildcard parametrizzat Ġbir<?> tindika l-familja tal-istanziazzjonijiet kollha tal- Ġbir interface irrispettivament mill-argument tat-tip.  It-tip parametrizzat tal-wildcard Lista<? jestendi Numru> attika l-familjar tat-tipi alla ta’ lista fejn it-tip ta’ element huwa sottotip ta’  Numru .  It-tip parametrizzat tal-wildcard Komparatur<? super String> hija l-familja tal-istanziazzjonijiet kollha tal- Komparatur interface гал tipi ta’ argument tat-tip li huma supertipi ta’ Spag.

Tip parametrizzat wildcard mhuwiex tip fis-sens regolari (differenti minn klassi/interface mhux parametrizzata jew tip mhux maħdum).

Tipi parametrizzati wildcard jistgħu jintużaw għat-tajpjar (bħal klassijiet u interfaces mhux parametrizzati):

  • bħala argument u tipi ta ‘ritorn ta’ metodi
  • bħala tip ta’ qasam jew varjabbli ta’ reference lokali
  • as tip ta ‘component ta’ argument tat-tip arrayas ta ‘tipi parametrizzati other
  • as tip ta’ mira fil-casts

Mhux biss it-tipi jistgħu jkunu ġeneriċi, iżda l-metodi jistgħu wkoll ikunu ġeneriċi. Metodi statiċi u mõi statiċi kif oukl kostrutturi jista ‘duknuk parametri tat-tip. Is-sintassi gåd-declaration tal-parametrie tat-tip formali hija simili gås-sintassi gåd tipi generici. Is-sektzjoni tal-parametru tat-tip hija delimitata minn parentesi angolari u sakrena vabat it-tip ta ‘ritorn tal-method. Is-sintassi u t-sintassi u t-sintasi huma identiċi għl-lista tal-parametri tat-tip ta’ tip ženeriku.

Hawn eżempju ta '‘generiku max metodu li jikkalkula l-akbar valur f’ġabra ta’ elementi ta’ tip mhux magħruf A .

Eżempju (ta’ metudo generiku):

Kollezzjonijiet tal-klassi {
  statiku pubbliku <A jestendi Komparable<A>> A max(Kollezzjoni< A > xs) {
    Iterator< A > xi = xs.iterator();
    A w = xi.li jmiss ();
    filwaqt li (xi.hasNext ()) {
      A x = xi.li jmiss ();
      jekk (w.compareTo(x) < 0) w = x;
    }
    lura w;
  }
} 

Il- max metodu għandu parametru tat-tip wieħed, imsemmi A .  Huwa tal-post tal-tip ta ‘element tal-ġbir li works fuku l-method. Il-parametru tat-tip telu bound; kelu jkun tip li huwa sottotip ta Komparabbli<A>

Eżempju (tal-istess tip ġeneriku, din id-darba ma limiti):

interface pubbliku Kumparabbli<T> {
  public int compareTo(T arg);
}
klassi pubblika TreeMap<Key testendi Comparable<Key> ,Data>{
  klassi statika privata Dħul<K,V> {
     K ċavetta;
     Valur V;
     Dħul<K,V> xellug = null;
     Dħul<K,V> dritt = null;
     Dħul<K,V> ġenitur;
  }
  Dħul tranżitorju privat Entry<Key,Data> għerq = null;
  ...
  Dħul privat<Key,Data> getEntry(ċavetta taċ-ċavetta) {
     Entry<Key,Data> p = għerq;
     Ċavetta k = ċavetta;
     filwaqt li (p != null) {
       int cmp = k. paragunTo(p.key) ; 
       jekk (cmp == 0)
         ritorn p;
       inkella jekk (cmp < 0)
         p = p.xellug;
       inkella 
         p = p.lemin; 
     }
     ritorn null;
  }
  public boolean containsKey (ċavetta taċ-ċavetta) {
     ritorn getEntry(key) != null;
  }
  ...
}

Fl-xembo ta ‘hawn fuq, il-parametru tat-tip Ewlenin għandha l-irbit Komparabbli<Key> .  L-ispeċifikazzjoni ta’ rbit għandha żewġ effetti:

  • Jagħti aċċess għall-metodi li l-irbit jispeċifika .  Fl-eżempju, l-irbit Komparabbli<Key> jagħti aċċess għall- qabbelTo metodu li rridu ninvokaw fl-implimentazzjoni ta tagħna TreeMap klassi.
  • Tipi biss “fil-limiti” jistgħu jintużaw għall-istanziazzjoni tat-tat-tip ġeneriku.   Fl-eżempju, tip parametrizzat bħal TreeMap<Number,String> tkun miċħuda, minħabba li t-tip Numru mhuwiex sottotip ta’ Komparabbli<Number> .  Tip parametrizzat simili TreeMap<String,String> ikun aċċettat, minħabba li t-tip String huwa fil-limiti, jiġifieri huwa subtip ta Komparabbli<String> .

Il-klassijiet, l-interfaces, u t-tipi kollha enum jistgħu jintużaw bħala parametru tat-tip marbut, inklużi tipi nested u interni.  La tipi primittivi u nor tipi ta’ array ma huma użati bħala parametru tat-tip bound.

Eżempji (tal-limiti tal-parameteri tat-tip):

klassi X0 <T testendi int > { ... }      // żball
klassi X1 <T testendi Oġġett[] > { ... } // żball
klassi X2 <T testendi Numru > { ... }
klassi X3 <T testendi Spag > { ... }
klassi X4 <T testendi Jiġi mħaddma > { ... }
klassi X5 <T testendi Thread.State > { ... }
klassi X6 <T testendi Lista > { ... }
klassi X7 <T testendi Lista<String> > { ... }
klassi X8 <T testendi Lista<? jestendi Numru> > { ... }
klassi X9 <T testendi Komparabbli<? super Numru> > { ... }
klassi X10<T testendi Mappa.Dħul<?,?> > { ... }

Il-kampjun tal-kodiċi juri li tipi primittivi bħal int u tipi ta’ firxa simili Oġġett[] mhumiex permessi bħala parametru tat-tip mabuto.

Tipi ta ‘klassi, like Numru jew Spag , u tipi ta’ interface, bħal Jiġi mħaddma , huma permessi as parameter tat-tip mabuto.

Enum tipi, bħal Thread.State huma permessi wkoll bħala parametru tat-tip marbut. Thread.State huwa eżempju ta’ tip ibbed użat bħala parametru tat-tip ibbed.  Tipi interni mõi statiċi huma permessi wkoll.

Tipi mhos processedi huma permessi as a parameter tat-tip mabuto; Lista hawn eżempju.

Tipi parametrizzati huma permessi bħala parametri tat-tip mabuto, inklużi tipi parametrizzati konkreti bħal Lista<String> , tipi parametrizzati wildcard delimitati bħal Lista<? jestendi Numru> u Komparabbli<? super Long> , u tipi parametrizzati wildcard bla limitu bħal Mappa.Dħul<?,?> .  Limitat li huwa tip parametrizzat as a wildcard allow as an argument tat-tip it-tipi alla li perpendien għall-familjar tat-tip li attika l-wildcard.  It-tip wildcard parametrizzat mebbut dībīb biss access ristrett għall-ħaldemen u l-metodi; ir-restrizzjonijiet jiddependu fuq it-tip ta’ wildcard.

Eżempju (ta’ pont parametrizzat bħala wildcard bħala parametru tat-tip mebut):

klassi X< T testendi List<? jestendi Numru> > {
  public void xiMetodu (T t) {
    t.add(New Long(0L));    // żball
    Numru n = t.remove(0);
  }
}
Test tal-klassi {
  public static void main(String[] args) {
     X<ArrayList< Twil >> x1 = ġdid X<ArrayList<Long>>(); 
     X<ArrayList< Spag >> x2 = ġdid X<ArrayList<String>>(); // żball
  }
}

Varjabbli ta’ referenza tat-tip T (il-parametru tat-tip) huma trattati bħal varjabbli ta’ reference ta’ tip wildcard (il-parametru tat-tip mabut).  Fl-tsembo nasana l-konsegwenza hija li l-kompilatur jiċħad l-invokazioni ta ‘metodi li they take an argument tat-tip “muchus donodani” li l-parametru tat-tip representativa, like Lista.add , because li l-irbit huwa tip parametrizat as a wildcard b’limitu ta’ fuq.
Fl-istes tymn l-irbit Lista<? jestendi Numru> jiddetermina t-tipi li jistgħu jintużaw bħala argumenti tat-tip. Il-kompilatur jaċċetta l-argumenti tat-tip kollha li jappartjenu għall-familja tat-tip Lista<? jestendi Numru> , i.e., is-sottotipi kollana ta ‘ Lista b’argument tat-tip li huwa sottotip ta’ Numru .

Parametu tat-tip jista’ huwa użat bħala l-irbit ta’ parametru tat-tip atone.

Eżempju (parametru tat-tip tat-ta’ użat bħala parametru marbut tat-ponta tat-tat):

klassi Triple <T> {
  privat T fst, snd, trd;
  pubbliku < U testendi T , V testendi T , W testendi T > Triplu(U arg1, V arg2, W arg3) {
    fst = arg1;
    snd = arg2;
    trd = arg3;
  }
}

F’dan l-eżempju l-parametru tat-tip T tal-klassi parametrizzata tintuża bħala marbuta tal-parametri tat-tip U ,  V u W ta’ metudo ta’ istanza parametrizata ta’ dik il-klassi.

Opportunitajiet oħra għall-użu ta’ parametri tat-tip as limiti ta’ parametri ta’ tip attn jinkludu sitwazzjonijiet fejn tip ibbed huwa definit välä tip generiku jew klassi lokali hija definita välä metudu generiku.  Huwa even permestes li is used for the tat-tip parameter as a binding ma’ for the tat-tip parameter attn fl-istes sessi tal-parametru tat-tip.

Marbuta li hija klassi gives access to lill-membri publiki alla, i.e., public areas, methods, u tipi ibbed. Il-kostrutturi biss ma severnx disponibbli, gëx m’hemm l-ebda garanzija li subklassi tal-irbit ilja l-istes kostrutturi like-irbit.

Eżempju (klassi ta’ użata bħala parametru rbit ta’ tat-tip):

klassi pubblika SuperKlassi {     // membri statiċi
    enum pubbliku EnumType {DAN, LI}
    Public static Oġġett staticField;
    public static void staticMethod () { ... }

    // membri mhux statiċi
    klassi pubblika InnerClass { ... }
    public Object nonStaticField;
    public void nonStaticMethod () { ... }

    // kostrutturi
    public SuperClass() { ... }

    // membri privati
    Private Object privateField; 

    ...
}

klassi finali pubblika SomeClass<T testendi SuperKlassi > {
    oġġett T privat;
    pubbliku SomeKlass(T t) { oġġett = t; } 

    Public String toString () {
        ritorn
         "tip nested statiku    : "+T.EnumType.class+"\n" 
        +"static field          : "+T.staticField+"\n"
        +"static method         : "+T.staticMethod()+"\n"
        +"tip imbejjed mhux statiku: "+T.InnerClass.class+"\n"
        +" non-static field      : "+object.nonStaticField+"\n"
        +"metodu mhux statiku     : "+object.nonStaticMethod()+"\n"
        +"costruttur           : "+(T())+"\n"                    // żball
        +"private member        : "+object.privateField+"\n"          // żball 
        ;
    }
}

L-irbit SuperKlassi Jagħti aċċess għal tipi nested, l-oqsma u metodi statiċi, u metodi statiċi.  Il-kostruttur biss mhux aċċessibbli.  Dan tämää il-kostrutturi ma jintirtux. Kull subklassi tiddefinixxi l-kostrutturi tas-superklassi u m’hainle sähe support l-kostrutturi tas-superklassi tas.  Għalhekk m’hemm l-ebda garanzija li subklassi ta ‘ SuperKlassi se utjo l-istes kostruttur bħas-superklassi ħawjo.

Il-kunset li fih Enum<E jestendi Enum<E>> “jidher hija d-statement tal- Enum klassi fil-pakkett java.lang :

klassi astratta pubblika Enum<E jestendi Enum<E>> {
  ...
}

It-tip Enum hija l-klassi bażi komuni tat-tipi kola ta’ enumerazzjoni.  Fil-Java tip ta’ enumerazzjoni like Kulur tiġi tradotta fi klassi Kulur li testendi Enum<Color> . L-iskop tas-superklassi Enum huwa li provide functionality li hija komuni gaat-tipi alla ta’ enumerazzjoni.

Hawn skeċċ tal-klassi Enum :

klassi astratta pubblika Enum< E testendi Enum<E>> timplimenta Comparable< E >, Serjalizzabbli {
  isem privat finali String;
  public final String name() { ... }   private final int ordinal;
  public final int ordinal () { ... }

  Enum protett(Isem String, int ordinal) { ... }

  Public String           toString() { ... }
  public final boolean ugwali (Oġġett ieħor) { ... }
  public final int hashCode() {... }
  protected final Object clone() throws CloneNotSupportedException {... }
  public final int compareTo( E o) { ... }

  pubbliku finali Class< E > getDeclaringClass() { ... }
  public static <T jestendi Enum<T>> T valueOf(Class<T> enumType, String name) { ... }
}

Il-characteristic sorprendenti fid-statement “ Enum<E jestendi Enum<E>> ” huwa l-fatt li l-klassi newva definita Enum u l-parametru tat-tip definit ġdid tiegħu E jidhru fil-limiti ta’ dak l-istes parameter tat-tip.  Dan ifisser li l- Enum it-tip geħal jijeme instanzjat ħal ħadhu mis-sottotipi ħawħ.  In order to understand why it makes sense, consider li kull tip ta ‘enum huwa tradott f’sottotip ta’ Enum .

Hawn hu t-tip ta’ enum maħdum Kulur :

enum Kulur {AĦMAR, BLUE, AĦDAR}

Il-kompilatur jittraduċiha fil-klassi li ġejja:

klassi finali pubblika Kulur testendi Enum<Color> {
  public static finali Kulur[] valuri() { return (Kulur[])$VALURI.clone(); }
  public static Color valueOf(Isem String) { ... }   privat Kulur(String s, int i) { super(s, i); }

  pubbliku statiku finali Kulur AĦMAR;
  pubbliku statiku finali Kulur BLUE;
  pubbliku statiku finali Kulur AĦDAR;

  privat statiku finali Kulur $VALURI[];

  statiku {
    AĦMAR = Kulur ġdid ("RED", 0);
    BLUE = Kulur ġdid ("BLUE", 1);
    AĦDAR = ġdid Kulur ("AĦDAR", 2);
    $VALURI = (Kulur ġdid [] { AĦMAR, BLUE, AĦDAR });
  }
}

Il-wirt għandu l-effett li l- Kulur tip jiret il-metodi kollha implimentati fi Enum<Color> .  Fosthom hemm il- qabbelTo metodu.  Il- Kulur. qabbelTo metodu għandu probabbilment jieħu a Kulur bħala argument.  Sabiex dan iseħħ klassi Enum huwa ġeneriku u l- Enum.compareTo metodu jieħu Enum parametru tat-tip ‘s E bħala argument.  Bħala riżultat, ittajpja Kulur derivati ​​minn Enum<Color> jiret a qabbelTo metodu li jieħu a Kulur kif u argument, exactly kif suppost.
Jekk nissekkjaw id-statement “ Enum<E jestendi Enum<E>> “Nistgħu naraw li dan il-mudell keħal diversi aspetti.

L-ewwel, hemm il-fatt li l-parametru tat-tip mabutu huwa t-tip t-tip t-tip tsifte: “ Enum <E jestendi Enum <E>> “. Jagħmel cicerant li biss sottotipi ta ‘tip Enum huma permessi bħala argumenti tat-tip. (Teoretikament, ittajpja Enum jista ‘jë istantanjat fuq tësëtë, bħal fi Enum<Enum> )

It-tieni, hemm il-fatt li t-tip mabat mal-parametru huwa t-tip parametrizat Enum <E> , li juża l-parametru tat-tip E as l-argument tat-tip tal-legat. Din id-statement assures li r-relationship ta’ wirt bejn sottotip u istazzjonijiet ta’ Enum huwa tal-forma X jestendi Enum<X> “. Sottotip bħal “ X jestendi Enum<Y> ” ma jistax jiġi ddikjarat minħabba l-argument tat-tip Y ma jkunx fil-limiti; sottotipi biss ta Enum<X> huma fil-limiti.

It-tielet, hemm il-fatt li Enum hija ġenerika fl-ewwel lok.  Dan ifisser li xi wħud mill-metodi tal-klassi Enum tūmi argument jew tangtura valur ta’ tip mội nội nội (jew lạn tại fuq tip nội nội nội). Kif nafu diġà, dan it-tip mhux magħruf aktar tard se jkun sottotip X ta Enum<X> .  Għalhekk, fit-tip parametrizzat Enum<X> , dawn il-metodi jinvolvu s-sottotip X , u jintirtu fis-sottotip X .  Il- qabbelTo metudu huwa example ta ‘tali metudu; tintiret mis-superklassi f’kull subklassi u teila firma spezifika tas-subklassi f’kull case.

Qosor, id-dikjarazzjoni “ Enum<E jestendi Enum<E>> ” jista' jiġi deċifrat bħala: Enum huwa tip ženeriku li jista ‘jje instanzjat biss gås-sottotipi sottotipi, u dawk is-sottotipi se jirtu xi metodi utli, li some of them take specific arguments tas-sottotip (jew otherwise depend fuq is-sottotip).

Parametri tat-Tip tal-Klassijiet Limitati Inferjuri

Il-parametri tat-tip jista’ podunu diversi limiti, like fi klassi Box<T testendi Number> {...} . Imma l-parametru tat-tip jista’ odjolo l-ebda limitu t’isfel, i.e., a construction like klassi Box<T kbir Numru> {...} mhux permess  Għaliex?  It-Answer hija: huwa inutli gëx ma jixtrilek nës, kekeu permesset.  Ejja naraw masimi il-parametri tat-tip ta’ classes tal-limiti inferjuri huma konfużi billi nesploraw xi meania limitu ta’ fuq parametri tat-tip.

Il-limitu ta’ fuq parameter tat-tip gehal tliet effetti:

    1. Instanzjazzjoni Ristretta. Il-limitu ta’ fuq strinġi s-sett ta’ tipi li can be used to-instanziajų tat-tip generiku.  Jekk niddekalaw a klassi Box<T testendi Number> {...} allura l-kompilatur jiżgura li biss sottotipi ta Numru jista’ jintuża bħala argument tat-tip.  Jiġifieri a Kaxxa<Number> jew a Box<Long> huwa permess, iżda a Kaxxa<Object> jew Box<String> tkun miċħuda

Eżempju (ta’ instantiation ristretta due to limitu ta’ fuq parameter tat-tip):
klassi Box<T testendi Numru> { 
   valur T privat; 
   Kaxxa pubblika (T t) { valur = t; } 
   ...
}  Test tal-klassi { 
   public static void main(String[] args) { 
       Box<Long> boxOfLong = ġdid Box<Long>(0L);   // multa
       Box<String> boxOfString = ġdid Box<String>(""); // żball: String mhix fil-limiti
   }
}

  1. Aċċess Għal Membri Mhux Statiċi. Il-limitu ta’ fuq gives access to methods and l-fields public mõis statiċi tal-limitu ta’ fuq.  Fl-implimentazzjoni ta' nana klassi Box<T testendi Number> {...} nistgħu ninvokaw il-metodi pubbliċi kollha mhux statiċi definiti fil-klassi Numru , bħal intValur() per eżempju.  Mingħajr il-limitu ta’ fuq il-kompilatur jirrifjuta kull invokazzjoni bħal din. Eżempju (l-aċċess ta’ għall-membri mhuwiex statiku minħabba li jillimita ta’ fuq il-parametru tat-tip):

klassi Box<T testendi Numru> { 
   valur T privat; 
   Kaxxa pubblika (T t) { valur = t; } 
   public int inkrement () { return value.intValue ()+1; } // <= ikun żball mingħajr in-Numru marbut
   ...
} 

    1. Tħassir tat-Tip. Il-limitu ta’ fuq l-aktar fuq ix-left is used for-delete tat-tip u jisbyrnytxxi l-parametru tat-tip fil-code tal-byte.  Fil Taghna klassi Box<T testendi Number> {...} l-okkorrenzi kollha ta T replaced bil-limitu ta’ fuq Numru .  Per eżempju, jekk klassi Kaxxa għandha qasam privat tat-tip T u metodu sett vojt (kontenut T) għall-setting ta ‘dan il-qasam privat, allura l-qasam ikun tat-tip Numru wara tħassir tat-tip u l-metodu jiġi tradott għal metodu sett null (kontenut tan-Numru) .

Example (tal-use tal-limitu ta’ fuq fuq parameter tat-tip fit-delete tat-tip – qabel tħassir tat-tip):
klassi Box< T testendi Numru > { 
   privat T valur; 
   Kaxxa pubblika( T t) { valur = t; } 
   ...
} 

      Example (tal-use tal-limitu ta’ fuq fuq parameter tat-tip fit-delete tat-tip –

wara

      tħassir tat-tip):

 

Kaxxa tal-klassi { 
   privat Numru valur; 
   Kaxxa pubblika( Numru t) { valur = t; } 
   ...
}

    Barra minn hekk, il-limitu ta ‘fuq l-aktar fuq ix-left gepare f’postes kliina, like casts imdaħħla awtomatikament u metodi ta’ pont.

Kieku limiti aktar baxxi kienu permessi fuq il-parametri tat-tip, liema effetti sekondarji jkollhom jew għandhom ikollhom? Jekk kostruzzjoni bħal klassi Box<T kbir Numru> {...} kiyan permessi, xi sabna?  Xi kudun l-effetti sakteuri 3 ta ‘limitu ta’ parameter tat-tip ta ‘fuq – instantiation ristretta, accesor gal membrum mõis statiku, delete tat-tip – meana gal limitu t’isfel?

Instanziazzjonijiet Ristretti. Il-kompilatur jista’jistrinġi s-sett ta’ tipi li can be used għall-instanziajų tat-tip generiku b’parametru tat-tip mabat aktar baxx.  Per eżempju, il-kompilatur jista ‘jippermetti istanziationzions like Kaxxa<Number> u Kaxxa<Object> minn a Box<T kbir Numru> u tirrifjuta istanziazzjonijiet bħal Box<Long> jew Kaxxa<Qasir> .  Dan ikun effett konformi mal-effett sakkere konstrukti describte gegal limiti ta’ parameter tat-tip ta’ fuq.

Aċċess Għal Membri Mhux Statiċi. Limitu ta’ parameter tat-tip aktar baxx ma dībūx access to xi particular methods lil hinn minn dawk li ntirtu mill-klassi Għan . Fl-eżempju ta Box<T kbir Numru> is-supertipi ta Numru m’havu sotto tipi ta’ Għan .  Il-kompilatur ma jistax jassumi li l-qasam tat-tip T huwa tat-tip Numru jew sottotip tiegħu.  Minflok, il-qasam tat-tip T jista ‘jkun ta’ any supertip ta ‘ Numru , bħal Serjalizzabbli jew Għan .  L-invokazioni ta ‘method like intValur() m’għdux tip-safe u l-kompilatur ħurų rykuzah. Konsegwentement, il-limitu tal-parametru tat-tip aktar baxx ma dībīwx access to membri mūs statiċi lil hinn minn dawk definiti fil-klassi. Għan u durga til til l-istes effett like “no bound”.

Tħassir tat-Tip .  Wara din il-linja tal-loġika, ma jagħmilx sens li tissostitwixxi l-okkorrenzi tal-parametru tat-tip bil-limitu l-aktar tax-xellug tiegħu.  Jiddikjara metodu bħall-kostruttur Kaxxa ( T t) bħala kostruttur Kaxxa ( Numru t) ma jagħmilx sens, meta wieħed iqis li T huwa mibdul b’supertip ta’ Numru .  An Għan jista ‘jë mgòddi êttuament lill-kostruttur f’istanziazzjoni Kaxxa<Object> u l-kostruttur jiċħadha.  Dan ikun ħażin ħażin.   Għalhekk, it-tħassir tat-tip jissostitwixxi l-okkorrenzi kollha tal-varjabbli tat-tip T skond it-tip Għan .  For darb’ogra, il-limitu t’isfel iljus l-estes effett as “l-ebda limitu”.

Teddijabih insemmu dak li jkun gejasalje jekk it-bwebi aktar baxxi _u_ limiti ta’ fuq kiyan permessi?   Personally, nga irrid namifak dwarha u nippreferi nippresentaha caat “mhux maniġagblibli”, jekk pomila.

Last line: dak kollu li “ kbir ” marbuta kekeu kusto inti hija r-restriction li supertipi biss ta ‘ Numru jistgħu jintużaw bħala argumenti tat-tip.  U anke dan huwa spiss mifhum ħażin.  MA jfissirx li klassi Box<T super Number> {...} fih biss każijiet ta’ supertipi ta’ Numru .  Pjutost bil-maqlub – kif juri l-maqboh hawn aatt!

Example (tal-use tal-limitu ta’ fuq fuq parameter tat-tip fit-delete tat-tip – qabel tħassir tat-tip):

klassi Box< T super Numru > {
   privat T valur;
   Kaxxa pubblika( T t) { valur = t; }
   ...
}

Example (tal-use tal-limitu ta’ fuq fuq parameter tat-tip fit-delete tat-tip – wara tħassir tat-tip):

Kaxxa tal-klassi {
   privat Għan valur;
   Kaxxa pubblika( Għan t) { valur = t; }
   ...
}

A klassi Box<T kbir Numru> {...} tkun tradotta bit-tħassir tat-tip għal a Kaxxa li jkun fih an Għan qasam u l-kostruttur tiegħu jiġi tradott għal Kaxxa (Oġġett t) . Dik hija fundamentalment differenti minn a klassi Box<T testendi Numru> {...} , li tkun tradotta għal a Kaxxa li jkun fih a Numru qasam u l-kostruttur tiegħu jiġi tradott għal Kaxxa (Numru t) . Konsegwentement, a Kaxxa<Number> instanzjat minn a klassi Box<T testendi Number> {...} ikun differenti minn a Kaxxa<Number> istanziazzjoni minn a klassi Box<T super Number> {...} , li x’akinya jikkawżaw konfużjoni.  Għal din ir-rawandawa limiti aktar lajisi ma majaknux sens fuq parametri tat-tip tal-classes.

 


 

Parametri tat-Tip tal-Metodi Limitati Inferjuri

Flimkien mal-metodi u t-tipi ta’ argumenti lashon, parameteru tat-tip b’limitu aktar baxx jista’ biswa jkun utli.

Example (ta’ metudo li jibbenefika minn parameteru tat-tip b’limitu aktar baxx):

klassi Pair<X,Y> {
   privat X l-ewwel;
   privat Y it-tieni;
   ...
   pubbliku < Super X , B super Y > B addToMap(Map<A,B> mappa) { // żball: parametru tat-tip ma jistax ikollu limitu inferjuri
      ritorn map.put(l-ewwel, it-tieni);
   }
}
Test tal-klassi { 
   public static void main(String[] args) { 
     Pair<String,Long> par = ġdid Pair<>("ABC",42L);
     Map<CharSequence, Number> map = HashMap<CharSequence, Number>();
     Numru numru = pair.addToMap (mappa);
   }
}

Il- addToMap() metudu adder il-tenzent tal-par galg mappa.  Any mappa li tista ‘żowden supertipi ta’ X u Y tagħmel.  Il-mappa poġġi () metudu junktura l-valur misjub fil-mappa for the key fil-mappa, jekk diġà hemm hemme ta ‘valur misjub fil-mappa for the key fil-mappa.  Il-valur tar-ritorn tal-mappa poġġi () metodu għandu jintbagħat lura mill- addToMap() metodu.  Taħt dawn iċ-ċirkostanzi wieħed jixtieq jiddikjara l-metodu kif muri hawn fuq: Il-mappa hija parametrizzata b’supertipi tal-parametri tat-tip tal-par u l- addToMap() It-tip ta’ ritorn tal-method huwa t-tip ta’ valur tal-mappa.

Peress li l-kompilatur ma pomidox limiti aktar laġis fuq il-parametri tat-tip neħtuðigu work-around.

Soluzzjoni oneh li tjejte f’čněnna hija l-uszu ta’ wildcard, because li l-wildcards jista’ poudunu limitu inferjuri.  Hawn work-around bl-uzu ta ‘wildcard.

Eżempju (ta’ soluzzjoni għall-ħġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġġ

klassi Pair<X,Y> {
   privat X l-ewwel;
   privat Y it-tieni;
   ...
   pubbliku Għan addToMap(Map< ? Super X , ? super Y mappa >) { 
      ritorn map.put(l-ewwel, it-tieni);
   }
}
Test tal-klassi { 
   public static void main(String[] args) { 
     Pair<String,Long> par = ġdid Pair<>("ABC",42L);
     Map<CharSequence, Number> map = HashMap<CharSequence, Number>();
     Numru numru = (Numru) pair.addToMap(mappa);
   }
}

It's working, save li m’hemm l-ebda mod biex tiddikjara t-tip ta ‘ritorn kif zasvero.  Ikun is-supertip ta Y li l-kompilatur jaqbad mit-tip tal-mappa, iżda m’hemm l-ebda sintassi biex huwa speċifikat.  M’gàndniex niddeclaraw it-tip ta’ ritorn a “ ? super Y “, għax “ ? super Y ” hija wildcard u mõi tip u mõi mõi permesset bäla tip ta ‘ritorn. M’ghàdniex għażla u žinjem nużaw Għan flok ponta ta ‘ritorn tal-method oura.  Dan it-tip ta’ ritorn riện đội mội specọc min-ịọ dịi jgạn lil min iċempel tal- addToMap() metudu fis-casting tal-valur tar-ritorn ‘l isfel minn Għan għall-ponta attwali tagħha.  Dan một nội tại dak li kellna f’mạnna.

Xogħol ieħor hija l-użu ta ‘methodi statiċi.  Hawnhekk huwa work-around b’methodu statiku velo smoos statiku.

Eżempju:

klassi Pair<X,Y> {
   privat X l-ewwel;
   privat Y it-tieni;
   ...
   pubbliku statiku < A , B ,X testendi A ,Y testendi B > B addToMap(Par<X,Y> par, Map< A , B mappa >) {
      ritorn map.put (par.ewwel, par.tieni);
   }
}
Test tal-klassi { 
   public static void main(String[] args) { 
     Pair<String,Long> par = ġdid Pair<>("ABC",42L);
     Map<CharSequence, Number> map = HashMap<CharSequence, Number>();
     Numru numru = Par .addToMap( par ,mappa);
   }
}

Il-ġeneriku addToMap() metudu telu erba ‘parametri tat-tip: two placeholders X u Y għat-tip tal-par u żewġ placeholders A u B għat-tip tal-mappa. A u B huma supertipi ta X u Y , għax X u Y   huma ddikjarati ma A u B bħala l-limiti ta’ fuq tagħhom. (Innota, li l-parametri tat-tip tal-metodu ġeneriku X u Y m’gàndha x’ọọcọ nội mal- Par tal-klassi X u Y parametri.  L-ismijiet X u Y re-use għall-method generiku biex taggithom faċilment rikonoxxibbli as l-parametri tat-tip tal-par. Bl-užu ta ‘erba’ parametri tat-tip wemo niddeklaraw it-tip ta ‘ritorn precisip kif zasvere: huwa l-istes tip bħat-tip ta’ valur tal-mappa.

Eżempju:

klassi SomeClass <T> {
  // initializer statiku, qasam statiku, metodu statiku
  statiku {
    XiKlassi< T Test > = ġdid SomeClass< T >(); // żball
  }
  privat statiku T globalInfo;          // żball
  pubbliku  statiku T getGlobalInfo () {        // żball
    ritorn globalInfo;
  }
  // initializer mhux statiku, qasam mhux statiku, metodu mhux statiku
  { 
    XiKlassi< T Test > = ġdid SomeClass< T >();
  }
  privat        T localInfo;
  pubbliku         T getLocalInfo () { 
    ritorn localInfo;
  }
  // tipi nested statiċi
  pubbliku statiku klassi Il-falliment jestendi l-Eċċezzjoni {
    finali privati T info;           // żball
    Falliment pubbliku( T t) { info = t; }      // żball
    pubbliku T getInfo () { ritorn informazzjoni; }    // żball
   }
  privat interface Kopjabbli {
    T kopja();                       // żball
  }
  privat enum Stat {
    VALIDU, INVALID;
    privat T info; // żball
    public void setInfo( T t) { info = t; } // żball
    pubbliku T getInfo () { ritorn informazzjoni; }    // żball
  }
  // tipi nested mhux statiċi
  pubbliku klassi Aċċessor {
    pubbliku T getInfo () { return localInfo; }
  }
}

L-example juri li l-parametru tat-tip ma žeže fil-kuntes statiku ta ‘klassi generika.  Juri wkoll li l-interfaces nested u t-tipi enum huma meqjusa bħala membri tat-tip statiku tal-klassi.  Klassijiet interni biss, i.e. classes ibdew mõis statiċi, can use il-parametru tat-tip tal-klassi generika li premila.

L-ambitu tal-parametru tat-tip ta’ interface huwa d-definizzjoni mühle ta’ l-interface, szweat seksi qasam jew tipi nested.  Dan huwa minħabba li l-fields u t-tipi nested definiti f’interface huma impliċitament statiċi.

Eżempju (ta ‘užu illegali ta’ parametru tat-tip f’interface ġeneriku):

interface SomeInterface <T> {
  // qasam
  XiKlassi< T Valur > = ġdid SomeClass< T >();  // żball
  // tip nested
  klassi Aċċessor {
    pubbliku T getInfo () {            // żball
      ritorn valur.getGlobalInfo ();
    }
  }
  // metodi
  T getValur();
}

L-eżempju juri li l-oqsma tal-‘interface huma impliċitament statiċi, sabiex il-parametru tal-ponta ma jistax jintuża kullimkien.  Bl-istes mod, il-klassi nested is considered as a klassi nested statika, klassi klassi interna, u għal din ir-rawandoa l-uzu tal-parametru tat-tip everywhere fil-klassi nested huwa illegali.

Soluzzjoni għall-klassijiet u l-interfaces statiċi mdaħħla:

Fil-każ ta’ classes u interfaces ibestjati statiċi din nŭi diżastru major.  Yalsho sluštų pomoje nigneraw il-klassi statika jew l-interface svetų.

Eżempju (soluzzjoni – iġġenerat t-tip static nested):

klassi Wrapper <T> {
  finali privati T theObject;

  tgeżwir pubbliku( T t) { theObject = t; }
  pubbliku T getWrapper () { ritorn theObject; }   pubbliku Immutabbli <T> makeImmutable () {
        ritorn ġdid Immutabbli <T> (l-Oġġett);
  }
  pubbliku Mutabbli <T> makeMutable () {
        ritorn ġdid Mutable <T> (l-Oġġett);
  }
  privat statiku <A> A makeClone(A theObject) { ... }

  klassi finali statika pubblika Immutabbli <A> { // issa hija klassi ġenerika
        finali privati A theObject;

        pubbliku Immutabbli( A arg) {
            theObject = makeClone(arg);
        }
        pubbliku A getWrappedItem () {
            ritorn makeClone(theObject);
        }
  }
  klassi statika pubblika Mutabbli <A> {
        ... simili ...
  }
}

M’hemm l-ebda soluzzjoni bħal din għal tipi enum nħbsa għaliex jistgħu jkunu ġeneriċi.

Soluzzjoni għall-klassijiet statiċi mdaħħla:

Jekk it-tip statiku nested huwa klassi, solution alternativa tkun iddawwar il-klassi statika fi klassi interna mhos statika.

Eżempju (soluzzjoni – użu klassi interna):

klassi Wrapper <T> {
  finali privati T theObject;

  tgeżwir pubbliku( T t) { theObject = t; }
  pubbliku T getWrapper () { ritorn theObject; }   public Mutable makeMutable () {
      ritorn dan. ġdid Mutabbli(theObject);
  }
  pubbliku Immutabbli makeImmutable () {
      ritorn dan. ġdid Immutabbli(theObject);
  }
  privat statiku <A> A makeClone(A theObject) { ... }

  klassi finali pubblika Immutabbli {  // m'għadhiex klassi statika
      finali privati T theObject;

      pubbliku Immutabbli( T arg) {
          theObject = makeClone(arg);
      }
      pubbliku T getWrappedItem () {
          ritorn makeClone(theObject);
      }
  }
  klassi pubblika Mutabbli 
        ... simili ...
  }
}

Din il-solution comes together ma ‘certu ammont ta’ overhead because li l-klassene interni kola dinjul hidden reference for exjemjo tat-tip ta ‘barra, li f’dan l-exjemlo la đenju điền u nhalga minnu tạng; ir-reference hidden hija biss bagalji.  Many times, il-classes interni huma kkombinati ma ‘interfaces in order to keep l-klassi interna detail ta’ implementation privata tal-klassi ta ‘closure.  Nistgħu nagħmlu l-listi hawn.

Eżempju (il-soluzzjoni rfinuta preċedenti):

klassi Wrapper <T> {
  finali privati T theObject;

  tgeżwir pubbliku( T t) { theObject = t; }
  pubbliku T getWrapper () { ritorn theObject; }   pubbliku Mutabbli <T> makeMutable () {
      lura dan.new Mutable(theObject);
  }
  pubbliku Immutabbli <T> makeImmutable () {
      lura dan.new Immutabbli(l-Oġġett);
  }
  privat statiku <A> A makeClone(A theObject) { ... }

  interface pubbliku Immutabbli<S> {
      S getWrappedItem();
  }
  interface pubbliku Mutable<S> {
      S getWrappedItem();
      void setWrappedItem (S arg);
  }
  privat klassi finali ImmutableImplementation jimplimenta Immutable<T> { 

      privat finali T theObject;

      Implimentazzjoni Immutabbli pubblika (T arg) {
          theObject = makeClone(arg);
      }
      pubbliku T getWrappedItem () {
          ritorn makeClone(theObject);
      }
  }
  privat klassi MutableImplementation jimplimenta Mutable<T> { 
        ... simili ...
  }
}

Kif tistgħu taraw, l-interfaces publici nested jeħtieġ li jkunu ġeneriċi filwaqt li l-classes privati ​​​​​​ta ‘Łóħro jistgħu jużaw il-parametru tat-tip tal-klassi gemetrama.

 

 

 

 

 

Ħalli Tweġiba