
Típusok
A Java egy statikusan beírt nyelv, ami azt jelenti, hogy a változó és annak típusának megadása előtt be kell jelentenie.
Például: int myInteger = 42;
Adjon meg általános típusokat.
Általános típusok
Meghatározás: „Az általános típus egy általános osztály vagy interfész, amelyet típusok felett paramétereznek.”
Lényegében az általános típusok lehetővé teszik egy általános, általános osztály (vagy módszer) megírását, amely különböző típusokkal működik, lehetővé téve a kód újrafelhasználását.
Ahelyett obj
, hogy int
típusnak, String
típusnak vagy bármilyen más típusnak adná meg, meg kell határoznia az Box
osztályt egy típusparaméter elfogadásához <
; Ezután n
használhatja a T-t, hogy az általános típust az osztály bármely részén képviselje.
Most írja be a kovarianciát és az ellentmondást.
Kovariancia és ellentmondás
Meghatározás
A variancia arra utal, hogy a bonyolultabb típusok közötti altípus hogyan viszonyul az alkotóelemek (forrás) közötti altípushoz.
A kovariancia és az ellentmondás könnyen megjegyezhető (és rendkívül informális) meghatározása:
- Kovariancia: fogadja el az altípusokat
- Ellentmondás: fogadja el a típusokat
Tömbök
A Java-ban a tömbök kovariánsak , ennek 2 következménye van.
Először is, egy típusú tömb tartalmazhat típusú T[]
elemeket T
és altípusait.
Number[] nums = new Number[5];nums[0] = new Integer(1); // Oknums[1] = new Double(2.0); // Ok
Másodszor, egy sor típus S[]
egy olyan altípusa T[]
, ha S
egy olyan altípusa T
.
Integer[] intArr = new Integer[5];Number[] numArr = intArr; // Ok
Azonban fontos megjegyezni, hogy: (1) numArr
egy referencia referencia típus Number[]
a „tényleges tárgy” intArr
a „tényleges típus” Integer[]
.
Ezért a következő sor nagyon jól összeáll, de futási időt produkál ArrayStoreException
(a kupacszennyezés miatt):
numArr[0] = 1.23; // Not ok
Futásidejű kivételt hoz létre, mert a Java futás közben tudja, hogy a „tényleges objektum” intArr
valójában egy tömb Integer
.
Generikusok
Az általános típusok esetében a Java a törlés miatt nem képes futás közben megismerni a típusparaméterek típusinformációit. Ezért futás közben nem tud védekezni a halomszennyezéssel szemben.
Mint ilyen, a generikumok változatlanok.
ArrayList intArrList = new ArrayList();ArrayList numArrList = intArrList; // Not okArrayList anotherIntArrList = intArrList; // Ok
A típusparamétereknek pontosan meg kell egyezniük a halomszennyezés elleni védelem érdekében.
De írja be a helyettesítő karaktereket.
Helyettesítő karakterek, kovariancia és ellentmondás
Helyettesítő karakterekkel a generikusok támogathatják a kovarianciát és az ellentmondást.
Az előző példát módosítva ezt kapjuk, ami működik!
ArrayList intArrList = new ArrayList();ArrayList numArrList = intArrList; // Ok
A „?” Kérdőjel helyettesítő karakterre utal, amely ismeretlen típust képvisel. Alacsonyabb korlátozású lehet, ami korlátozza az ismeretlen típust egy meghatározott típusra vagy annak szupertípusára.
Ezért a 2. sorban ? super Integer
„bármilyen típus, amely egész szám vagy annak felső típusa”.
Használhatja továbbá a helyettesítő karakterek felső határát is, amelyek az ismeretlen típust meghatározott típusnak vagy altípusának korlátozzák ? extends Integer
.
Csak olvasható és csak írható
A kovariancia és az ellentmondás érdekes eredményeket hoz. A kovariáns típusok csak olvashatók, míg az ellentmondásos típusok csak írhatók.
Ne feledje, hogy a kovariáns típusok elfogadják az altípusokat, tehát ArrayList
er> can contain any object that is either
of a
Number type or its subtype.
In this example, line 9 works, because we can be certain that whatever we get from the ArrayList can be upcasted to a
Number
type (because if it extends Number
, by definition, it is a Number
).
But
nums.add()
doesn’t work, because we cannot be sure of the “actual type” of the object. All we know is that it must be a Number
or its subtypes (e.g. Integer, Double, Long, etc.).
With contravariance, the converse is true.
Line 9 works, because we can be certain that whatever the “actual type” of the object is, it must be
Integer
or its supertype, and thus accept an Integer
object.
But line 10 doesn’t work, because we cannot be sure that we will get an
Integer
. For instance, nums
could be referencing an ArrayList of Objects
.
Applications
Therefore, since covariant types are read-only and contravariant types are write-only (loosely speaking), we can derive the following rule of thumb: “Producer extends, consumer super”.
A producer-like object that produces objects of type
T
can be of type parameter
T>, while a consumer-like object that consumes objects of
type T can be of type para
meter
super T>.