Limitations de l'inférence de type de variable locale en Java

Dec 15 2022
Java 10 a introduit une fonctionnalité notable : l'inférence de type de variable locale. Cela nous permet de déclarer des variables locales sans spécifier le type à l'aide du mot-clé var, le compilateur déduit automatiquement son type.
Icônes Java créées par Flat Icons — Flaticon

Java 10 a introduit une fonctionnalité notable : l'inférence de type de variable locale. Cela nous permet de déclarer des variables locales sans spécifier le type à l'aide du mot- varclé, le compilateur déduit automatiquement son type. Cela réduit les déclarations passe-partout complexes et rend le code propre.

Exemple (ancienne méthode de déclaration) :

BufferedInputStream bufferedInStream = new BufferedInputStream(new FileInputStream("data.txt"));
List<String> list = new ArrayList<>();
Map<String, Integer> map = new HashMap<>();

var bufferedInStream = new BufferedInputStream(new FileInputStream("data.txt"));
var list = new ArrayList<String>();
var map = new HashMap<String, Integer>();

1. Niveau de classe

Lorsque nous parlons d'inférence de type de variable "locale", nous pouvons l'utiliser strictement dans le contexte local d'une méthode. Nous ne pouvons pas déclarer une variable à l'intérieur d'une classe (statique ou instance) en utilisant le mot- varclé. Le compilateur renvoie une erreur de compilation s'il tente de le déclarer dans une classe.

class Example {
    int rollNumber;
    var name; // Compiler Error! - Cannot resolve symbol 'var'
}

Vous devez affecter une valeur non nulle à la variable lors de la déclaration afin que le compilateur puisse déduire son type. L'assignation d'une référence nulle à une variable rend difficile au compilateur de déduire son type. Par conséquent, l'affectation nulle n'est pas autorisée lors de la déclaration.

public static void main(String[] args) {
    var name = null; // Compiler Error! - Cannot infer type: variable initializer is 'null'
}

public static void main(String[] args) {
    var name = "hello";
    name = null; // Valid now!
}

Java nous permet d'initialiser plusieurs variables du même type dans une seule instruction séparée par une virgule. int length = 10, breadth = 20, height = 30;Cependant, cela n'est pas autorisé lorsque vous utilisez le var.

public static void main(String[] args) {
    var length = 10, breadth = 20, height = 30; // Compiler Error! 'var' is not allowed in a compound declaration
}

L'initialisation d'un tableau n'est pas autorisée sans spécifier son type lors de l'initialisation.

public static void main(String[] args) {
    var a = { 1, 2, 3 }; // Compiler Error! Array initializer is not allowed here
    var[] b = { 1, 2, 3 }; // Compiler Error! Unexpected token.
    var[] c = new int[] { 1, 2, 3 }; // Compiler Error! Unexpected token.

    var d = new int[] { 1, 2, 3 }; // Valid!
}

En Java 10, varétait limité uniquement aux variables locales. Java 11 a étendu la portée des vararguments à Lambda.

Exemple :

BiConsumer<String, String> example = (var s1, var s2) -> System.out.println(s1 + s2); // Valid!

BiConsumer<String, String> example = (var s1, String s2) -> System.out.println(s1 + s2); // Compiler error. Cannot mix 'var' and explicitly typed parameters in lambda expression

forloop nous permet d'initialiser plusieurs variables. Java 10 nous permet d'utiliser les varboucles on for. Cependant, la déclaration composée n'est pas autorisée ici non plus.

for (var i = 0; i < 10; i++) { // Valid! Single var declaration is allowed
    System.out.println(i);
}


for (var i = 0, j = 10 ; i < 10; i++, j--) { // Compiler error! 'var' is not allowed in a compound declaration
    System.out.println(i + j);
}

Java nous permet de déclarer plusieurs blocs catch afin de traiter différemment diverses exceptions. Nous devons spécifier le type d'exception dans le bloc catch pour gérer l'exception particulière. Par conséquent, l'utilisation de var dans le bloc catch rend difficile de savoir à quel bloc catch l'exception doit être transmise.

try {
    var input = new FileReader("hello.txt");
} catch (var e) { // Compiler Error. Not allowed in catch block
    System.out.println("Error occured");
}

L'inférence de type de variable locale est une amélioration notable apportée à Java 10. Elle réduit la déclaration passe-partout. Il ne peut être utilisé que dans le contexte local de la méthode. Il est illégal de l'utiliser au niveau de la classe et ne peut pas effectuer d'affectation nulle, de déclaration composée, de déclaration de tableau, d'arguments lambda mixtes et de déclaration composée dans une boucle for et un bloc catch.