Question au sujet des generics (Java8/Java7)
Salut,
J'ai toujours quelques problèmes de compréhension de certains cas de syntaxe au sujet des classes/méthodes paramétrées et je suis tombé sur un cas qui ne m'aide pas à une meilleure compréhension.
Voici une classe :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| public class Optional<T> {
private final static Optional<?> EMPTY = new Optional<>();
private final T value;
private Optional() {
this.value = null;
}
public static <T> Optional<T> empty() {
@SuppressWarnings("unchecked")
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
private Optional(T value) {
if (value == null) {
throw new NullPointerException();
}
this.value = value;
}
public static <T> Optional<T> of(T value) {
return new Optional<T>(value);
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
public T get() {
if ( value == null ) {
throw new NoSuchElementException("No value present");
}
return value;
}
public boolean isPresent() {
return value!=null;
}
} |
Cette classe compile en Java8.
Maintenant, je tente de la compiler en Java7 et j'ai une erreur dans cette méthode (Type mismatch) :
Code:
1 2 3
| public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
} |
Que je peux corriger en faisant un cast (Optional<T) sur la valeur retournée, mais qui est toutefois signalé en "unchecked". Là, déjà, ça m'interpelle, mais bon admettons. J'écris donc :
Code:
1 2 3 4
| @SuppressWarnings("unchecked")
public static <T> Optional<T> ofNullable(T value) {
return value == null ? (Optional<T>)empty() : of(value);
} |
et ça compile sans warning en Java7.
Là, je commence à être un peu perdu : pourquoi l'appel de of() ne nécessite pas de cast, alors que celui de empty() si. A part l'argument de of(), je ne vois pas de différence dans la déclaration des deux méthodes. Et je ne vois en quoi l'argument pourrait avoir une influence ici. Encore, je serais obligé de caster les deux, je me dirais qu'il y a un point de la doc que je n'ai pas bien lu, ou pas compris, dans le fonctionnement des génériques. Mais, là, j'avoue que ça m'échappe.
Encore plus quand j'écris :
Code:
1 2 3 4 5 6 7 8
| public static <T> Optional<T> ofNullable(T value) {
if ( value==null ) {
return empty();
}
else {
return of(value);
}
} |
et que ça compile, en Java7 (en Java5 d'ailleurs aussi, avec la petite modification nécessaire de private final static Optional<?> EMPTY = new Optional<Object>();).