[Java] Quand var doit être utilisé et quand il ne doit pas être utilisé

Aperçu

À partir de Java 10, vous pouvez utiliser l'inférence de type de variable locale à l'aide de var. Bien que cela soit pratique, cela peut réduire la lisibilité s'il n'est pas utilisé correctement, j'ai donc réfléchi au moment de l'utiliser. (Java 10 est sorti il y a plus d'un an, c'est donc une autre histoire maintenant)

Environnement d'exploitation

Java 10 ou version ultérieure

Qu'est-ce que var en premier lieu?

Lors de la déclaration d'une variable locale, vous pouvez omettre la spécification de type en écrivant "var" au lieu de spécifier le type de variable. C'est ce qu'on appelle l'inférence de type.

//Style d'écriture traditionnel
String s = "hogehoge";
//Comment écrire avec var
var s = "hogehoge";
//Méthode de classe String toUpperCase()(La variable s est reconnue comme de type chaîne)
System.out.println(s.toUpperCase());  // => HOGEHOGE

De quoi es-tu heureux

Quelle que soit la longueur du nom du modèle, tout ce que vous avez à faire est d'écrire "var", ce qui facilite l'écriture. Il devrait également être plus facile à lire car il élimine les informations redondantes et est soigné.

//Style d'écriture traditionnel
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
//Comment écrire avec var
var dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");

Le nom assez long DateTimeFormatter est apparu deux fois, et je pense que c'est un peu plus facile à écrire et à lire.

Pas de saisie dynamique!

L'utilisation de var est toujours typée statiquement. La variable n'est pas détypée, elle est simplement typée automatiquement lorsque la variable est définie. Vous ne pouvez pas réaffecter une valeur d'un autre type à une variable une fois définie avec var. (Erreur de compilation) [^ 1]

[^ 1]: Bien sûr, cela ne s'applique pas aux types compatibles avec l'affectation tels que les sous-classes.

//Puisque le côté droit est un littéral de chaîne, la variable s est automatiquement de type String
var s = "hogehoge";
//Puisque s est une chaîne, vous ne pouvez pas affecter une valeur d'un autre type tel que int.
s = 123;
//Erreur:
//Type incompatible:int java.lang.Impossible de convertir en chaîne:
//  s = 123;
//      ^-^

Il s'agit également d'une erreur de compilation si le type ne peut pas être spécifié de manière unique depuis le côté droit lors de la définition d'une variable avec var.

//Erreur de compilation car null ne sait pas de quel type il s'agit
var v = null;
//Erreur:
//Impossible de déduire le type de variable locale v
//    (Initialiseur variable'null'est)
//  var v = null;
//  ^-----------^

C'est complètement différent de JavaScript var etc., alors ne vous méprenez pas.

Utiliser ou non var

Vous savez ce qu'est var. (peut être) À partir de là, comme le titre l'indique, nous examinerons quand utiliser var et quand ne pas l'utiliser.

Quand utiliser var

En un mot, c'est un cas où vous pouvez dire en un coup d'œil quel type vous avez en regardant le côté droit. Plus précisément, les cas suivants sont supposés.

Lors de l'instanciation sur le côté droit

//Puisque le nom du modèle est écrit tel quel sur le côté droit, vous pouvez voir de quel type il s'agit en un coup d'œil
var date = new Date();

var scanner = new Scanner(System.in);

var list = new ArrayList<String>();

Si le côté droit est littéral

//Puisque le côté droit est un littéral de chaîne de caractères, vous pouvez voir en un coup d'œil qu'il s'agit d'un type String
var s = "hogehoge";
//Puisque le côté droit est un littéral entier, vous pouvez voir en un coup d'œil qu'il s'agit d'un type int
var n = 123;

Lors de l'appel d'une méthode qui peut facilement deviner le type de retour sur le côté droit

//Vous pouvez le dire car le nom de la méthode contient le nom du type
var br = Files.newBufferedReader(Paths.get("filename"));

//Obtenez la date et l'heure actuelles, mais comme il s'agit d'une méthode statique de LocalDateTime, vous pouvez deviner qu'il s'agit d'un type LocalDateTime.
var date = LocalDateTime.now();

//Puisque vous obtenez une instance de calendrier, vous pouvez deviner qu'il s'agit d'un type de calendrier.
var cal = Calendar.getInstance();

Si vous ne devez pas utiliser var

Le contraire de quand var doit être utilisé, en un mot, lors de l'appel d'une méthode dont le type de retour ne peut pas être déduit avec précision en regardant le côté droit.

// Date#getTime()
//Puisqu'il existe différents types qui représentent des dates, vous ne pouvez pas le dire uniquement par "Heure" (en fait, c'est un type long).
var time = date.getTime();

// Path#getFileName()
//Est-ce une chaîne parce que c'est un nom de fichier? (En fait, type de chemin)
var filename = path.getFileName();

// File#getAbsolutePath()
//Puisqu'il existe un chemin, est-ce également un type de chemin? (En fait de type chaîne)
var path = file.getAbsolutePath();

// Files#copy(Path, OutputStream)
//J'ai reçu quelque chose mais je ne sais pas ce que c'est. Cela ressemble à une valeur numérique, donc int? (En fait, une valeur de type long qui représente le nombre d'octets copiés)
var size = Files.copy(path, out);

prime

Lorsqu'elle est utilisée en combinaison avec une classe anonyme, vous pouvez définir une méthode qui n'est valide que dans une méthode particulière. Cela n'a rien à voir avec le sujet principal, mais je vais l'écrire car cela peut être utile.

Main.java


public class Main {
    public static void main(String[] args) {
        // func.capitalize()Peut être appelé avec
        //func est une variable locale et ne peut pas être appelée depuis l'extérieur de cette méthode
        var func = new Object() {
            private String capitalize(String s) {
                return s.substring(0, 1).toUpperCase() + s.substring(1, s.length()).toLowerCase();
            }
        };

        System.out.println(func.capitalize("tokyo")); // => Tokyo
        System.out.println(func.capitalize("TOKYO")); // => Tokyo
    }
}

Résumé

Lien de référence

Recommended Posts

[Java] Quand var doit être utilisé et quand il ne doit pas être utilisé
Map keySet, les valeurs ne doivent pas être utilisées
[Java10] Veillez à utiliser ensemble var et génériques
Syntaxe et conditions d'occurrence d'exception pouvant être utilisées lors de la comparaison avec null en Java
Le ressort doit être suspecté lorsque les commandes Rails ne fonctionnent pas correctement
Pourquoi Java Vector n'est pas utilisé
java jshell et var sont trop recommandés!
[Rails] [Note] Quand ajouter = à <%%> et quand pas
[NetBeans] Story quand il ne démarre pas
[Java] Lors de la vérification du format URL avec Bean Validation, il peut être préférable de ne pas utiliser @URL de Hibernate Validator.
[CentOS8] Puisque la commande javac n'a pas pu être utilisée, installez l'environnement de développement java.
Soyez prudent avec les demandes et les réponses lors de l'utilisation de Serverless Framework avec Java
ValidationMessages.properties ne doit pas être multiple sur le chemin de classe
Utilisez le modèle de repos Gekitsuyo pour la communication REST
Points à prendre en compte lors de l'écriture de Java
Instruction de commutation Java et pause, Kotlin lorsque l'expression ...
À propos de var utilisé en Java (type de variable locale)
Le servlet Java doit être conscient de l'environnement multithread
Pourquoi la comparaison de classe de type chaîne Java (==) ne peut pas être utilisée
[Java] Précautions lors du référencement dans une classe parent et de l'instanciation dans une classe enfant
L'histoire selon laquelle la méthode d'initialisation de variable appelée par le constructeur Java ne doit pas être remplacée