Vad innebär det fetmarkerade i följande kodsnutt? Jag förstår generics men jag förstår inte vad följden blir att skriva sådär före returtypen.
public class UsingReflection<T> {
public static [b]<T>[/b] void createInstance(Class<T> clazz) {
T instance;
try {
instance = clazz.newInstance(); // does not work for every class
} catch (InstantiationException e) {
//...
} catch (IllegalAccessException e) {
//...
}
//...
}
}
Vad innebär det fetmarkerade i följande kodsnutt? Jag förstår generics men jag förstår inte vad följden blir att skriva sådär före returtypen.
Därför att annars skulle kompilatorn tro att T var ett klassnamn, så din kod skulle inte funka. Statiska metoder kan inte använda de typparametrar som deras klass tar emot - typparametrar är icke-statiska - "per objekt", inte "per klass". Exempelvis är new Foo<X>() av samma klass som new Foo<Y>(), till skillnad från hur det är i t.ex. C# och C++.
Därför att annars skulle kompilatorn tro att T var ett klassnamn, så din kod skulle inte funka. Statiska metoder kan inte använda de typparametrar som deras klass tar emot - typparametrar är icke-statiska - "per objekt", inte "per klass". Exempelvis är new Foo<X>() av samma klass som new Foo<Y>(), till skillnad från hur det är i t.ex. C# och C++.
Nu vet jag inte riktigt... svarade du verkligen på min fråga nu? Att kompilatorn skulle tro att T var ett klassnamn utan < > förstår jag. Men vad innebär det att skriva <T> framför returtypen? Att typparametrarna är per-objekt och inte per-klass är jag också med på. Men jag förstår inte metodsignaturen:
public static <T> void createInstance(Class<T> clazz)
Du deklarerar den generiska variabeln T på det sättet.
public static <T> void createInstance(Class<T> clazz)
Denna rad betyder "skapa en generisk metod som tar en typ med variabelnamn T och deklarera den som public static void createInstance(Class<T> clazz)". Eftersom man vill deklarera en variabel innan den kan användas så vill man ha den så tidigt som möjligt, och det blir då strax före returtypen.
Det går ju faktiskt att skriva:
public <T> T downCast(Class<? extends T> t){
return (T) t;
}
(men den är svår att använda...)
Varför man kaplsar in typen T i statiska anrop beror helt enkelt på att man vill komma åt klassen och inte objekten. Klassen Class är även den generisk numera och till denna kan man ge en typ. Class<T> kan man läsa som ta typ T och låt den bli inkapslad i en Class, för att man ska kunna komma åt det man kan komma åt på en klass... t.ex. statiska metoder.