Java >> Java tutorial >  >> Java

Hvorfor kan en generisk typeparameter ikke have en nedre grænse i Java?

Dybest set er det ikke nyttigt nok.

Jeg tror, ​​dit eksempel påpeger den eneste fordel ved en nedre grænse, en funktion som ofte stillede spørgsmål kalder Restricted Instantiation :

Den nederste linje er:alt, hvad en "super" bundet ville købe dig er begrænsningen at kun supertyper af tal kan bruges som type-argumenter . ....

Men som de andre indlæg påpeger, kan anvendeligheden af ​​selv denne funktion være begrænset.

På grund af arten af ​​polymorfi og specialisering er øvre grænser langt mere nyttige end nedre grænser, som beskrevet af ofte stillede spørgsmål (Adgang til ikke-statiske medlemmer og Typesletning ). Jeg formoder, at kompleksiteten introduceret af nedre grænser ikke er sin begrænsede værdi værd.

OP:Jeg vil tilføje, at jeg synes, du viste, at det er nyttigt, bare ikke nyttigt nok. Kom med de uigendrivelige killer use cases, og jeg støtter JSR. :-)


Specifikationen taler f.eks. om nedre grænser for typeparametre

4.10.2

en typevariabel er en direkte supertype af dens nedre grænse.

5.1.10

en frisk typevariabel ... hvis nedre grænse

Det ser ud til, at en typevariabel kun har en (ikke-nul) nedre grænse, hvis den er en syntetisk som et resultat af jokertegn. Hvad hvis sproget tillader nedre grænser for alle typeparametre? Sandsynligvis forårsager det ikke mange problemer, og det er kun udelukket for at holde generiske artikler enklere (nå ...) Opdater det siges, at teoretisk undersøgelse af parametre af lavere grænser ikke er grundigt udført.

Opdatering:et papir, der hævder, at nedre grænser er ok:"Java Type Infererence Is Broken:Can We Fix It" af Daniel Smith

TRÆK TILBAGE:Følgende argument er forkert. OP's eksempel er legitimt.

Dit særlige eksempel er ikke særlig overbevisende. For det første er det ikke type sikkert. Den returnerede liste er faktisk en List<String> , er det usikkert at se det som en anden type. Antag, at din kode kompilerer:

    List<CharSequence> l2 = createArrayListFullOfEmptyStrings(5);

så kan vi tilføje non-String til det, hvilket er forkert

    CharSequence chars = new StringBuilder();
    l2.add(chars); 

Nå en List<String> er ikke, men lidt som en liste over CharSequence. Dit behov kan løses ved at bruge jokertegn:

public static  List<String> createArrayListFullOfEmptyStrings(int size)  

// a list of some specific subtype of CharSequence 
List<? extends CharSequence> l2 = createArrayListFullOfEmptyStrings(5);

// legal. can retrieve elements as CharSequence
CharSequence chars = l2.get(0);

// illegal, won't compile. cannot insert elements as CharSequence
l2.add(new StringBuilder());

Java tag