V Jave platí zásada, že generiká po skompilovaní zabudnú (tzv.
type erasure), inými slovami, v bajtkóde sa žiadne údaje o generických typoch neudržíavajú a všade namiesto T si predstavte Object.
Z vašej triedy tak ostane
public class Vector2D {
public Object x, y;
public Vector2D() {
this.x = (Object) (Number) 0;
this.y = (Object) (Number) 0;
}
public String getType() {
if (x instanceof Float) {
return "Float";
} else if (x instanceof Integer) {
return "Integer";
} else {
return null;
}
}
}
Ďalej: vaša 0 je literál, ktorý má dátový typ
int (po autoboxingu, t. j. automatickej zmene primitívu na objektový typ je to Integer). Vy pretypujete Integer na Number a následne z neznámych dôvodov tento Number na Object. Obe pretypovania sú prakticky zbytočné, lebo pretypovaním nepresvedčíte kompilátor, že váš literál 0 je zrazu float, či double (float literály sa v Jave uvádzajú ako 0.0f).
Vo vašich inštančných premenných máte teda x, y rovné 0 typu int/Integer a bez ohľadu na generikum (ktoré sa zabudne) vidíte na výstupe správnu hodnotu "Integer".
Reálne riešenie: vždy musíte dodať nielen generikum, ale aj konkrétny typ v podobe inštancie Class-u.
public class Vector2D<T extends Number> {
private T x;
private T y;
private Class<T> elementType;
public Vector2D(Class<T> elementType) {
this.x = (T) 0;
this.y = (T) 0;
this.elementType = elementType;
}
public String getType() {
return elementType.getName();
}