Comment déclarer correctement des méthodes en Java?

Chaque programme Java intéressant que nous avons vu possède une méthode main(). Vous pouvez écrire d’autres méthodes aussi. Par exemple, vous pouvez écrire une méthode basique pour faire une sieste, comme illustré dans le code de bloc ci dessous.

Déclaration de méthode

public final void faireSieste(int minutes) throws InterruptedException {
    // faire une sieste
}

Ceci s’appelle une déclaration de méthode, qui spécifie toutes les informations nécessaires pour appeler la méthode. Il y a beaucoup de parties, et nous couvrons chacune d’entre elles en détail. Deux de ces parties—le nom de la méthode et la liste de paramètres—sont appelées la signature de méthode. La signature de méthode fournit des instructions sur comment les appelants peuvent référencer cette méthode. La signature de méthode n’inclut pas le type de retour et les modificateurs d’accès, qui contrôlent la méthode peut être référencée.

Le Tableau est une brève référence aux éléments d’une déclaration de méthode. Ne vous inquiétez pas si cela semble beaucoup d’information—d’ici la fin de ce chapitre, tout s’assemblera.

Parties d’une déclaration de méthod

ÉlémentValeur dans l’exemple faireSieste()Obligatoire?
Modificateur d’accèspublicNon
Spécificateur optionnelfinalNon
Type de retourvoidOui
Nom de méthodefaireSiesteOui
Liste de paramètres(int minutes)Oui, mais peut être des parenthèses vides
Signature de méthodefaireSieste(int minutes)Oui
Liste d’exceptionsthrows InterruptedExceptionNon
Corps de méthode{
// faire une sieste
}
Oui, sauf pour les méthodes abstract

Pour appeler cette méthode, utilisez simplement la signature de méthode et fournissez une valeur int entre parenthèses:

faireSieste(10);

Commençons par examiner chacune de ces parties d’une méthode basique.

Modificateurs d’Accès

Un modificateur d’accès détermine à partir de quelles classes une méthode peut être accédée. Pensez-y comme un gardien de sécurité. Certaines classes sont de bons amis, certaines sont des parents éloignés, et d’autres sont des étrangers complets. Les modificateurs d’accès aident à faire respecter quand ces composants sont autorisés à communiquer entre eux. Java offre quatre choix de modificateurs d’accès:

  • private. Le modificateur private signifie que la méthode ne peut être appelée qu’à partir de la même classe.
  • Accès Package. Avec l’accès package, la méthode ne peut être appelée que depuis une classe dans le même package. Celui-ci est délicat car il n’y a pas de mot-clé. Vous omettez simplement le modificateur d’accès. L’accès package est parfois appelé package-private ou accès par défaut (même dans ce livre!).
  • protected. Le modificateur protected signifie que la méthode ne peut être appelée que depuis une classe dans le même package ou une sous-classe.
  • public. Le modificateur public signifie que la méthode peut être appelée de n’importe où.

Pour simplifier, nous nous intéressons principalement aux modificateurs d’accès appliqués aux méthodes et aux champs dans ce chapitre. Les règles pour les modificateurs d’accès sont également applicables aux classes et autres types que vous apprendrez dans le Chapitre 7, “Au-delà des Classes”, comme les interfaces, les énumérations et les records.

Nous explorons l’impact des différents modificateurs d’accès plus tard dans ce chapitre. Pour l’instant, maîtrisez l’identification de la syntaxe valide des méthodes.

Nous verrons des exemples pratiques au fur et à mesure que nous aborderons chacun des éléments de méthode dans ce chapitre. Assurez-vous de comprendre pourquoi chacun d’entre eux est une déclaration de méthode valide ou invalide. Faites attention aux modificateurs d’accès en déterminant ce qui ne va pas avec ceux qui ne compilent pas lorsqu’ils sont insérés dans une classe:

public class SortieParc {
    public void sauter1() {}
    default void sauter2() {} // NE COMPILE PAS
    void public sauter3() {} // NE COMPILE PAS
    void sauter4() {}
}

La méthode sauter1() est une déclaration valide avec un accès public. La méthode sauter4() est une déclaration valide avec un accès package. La méthode sauter2() ne compile pas parce que default n’est pas un modificateur d’accès valide. Il existe un mot-clé default, qui est utilisé dans les instructions switch et les interfaces, mais default n’est jamais utilisé comme modificateur d’accès. La méthode sauter3() ne compile pas car le modificateur d’accès est spécifié après le type de retour.

Spécificateurs Optionnels

Il existe un certain nombre de spécificateurs optionnels pour les méthodes, présentés dans le Tableau. Contrairement aux modificateurs d’accès, vous pouvez avoir plusieurs spécificateurs dans la même méthode (bien que toutes les combinaisons ne soient pas légales). Lorsque cela se produit, vous pouvez les spécifier dans n’importe quel ordre. Et puisque ces spécificateurs sont optionnels, vous êtes autorisé à n’en avoir aucun. Cela signifie que vous pouvez avoir zéro ou plusieurs spécificateurs dans une déclaration de méthode.

Comme vous pouvez le voir dans le Tableau, quatre des modificateurs de méthode sont couverts dans les chapitres ultérieurs, et les deux derniers ne sont même pas dans le cadre de cet examen (et sont rarement utilisés dans la vie réelle). Dans ce chapitre, nous nous concentrons sur l’introduction de ces modificateurs. Leur utilisation nécessite souvent beaucoup plus de règles.

Spécificateurs optionnels pour les méthodes

ModificateurDescriptionChapitre couvert
staticIndique que la méthode est un membre de l’objet de classe partagéChapitre 5
abstractUtilisé dans une classe abstraite ou une interface lorsque le corps de la méthode est excluChapitre 6
finalSpécifie que la méthode ne peut pas être remplacée dans une sous-classeChapitre 6
defaultUtilisé dans une interface pour fournir une implémentation par défaut d’une méthode pour les classes qui implémentent l’interfaceChapitre 7
synchronizedUtilisé avec du code multithreadChapitre 13
nativeUtilisé lors de l’interaction avec du code écrit dans un autre langage, comme C++Hors de portée
strictfpUtilisé pour rendre les calculs à virgule flottante portablesHors de portée

Bien que les modificateurs d’accès et les spécificateurs optionnels puissent apparaître dans n’importe quel ordre, ils doivent tous apparaître avant le type de retour. En pratique, il est courant de lister le modificateur d’accès en premier. Comme vous l’apprendrez dans les chapitres à venir, certains spécificateurs ne sont pas compatibles les uns avec les autres. Par exemple, vous ne pouvez pas déclarer une méthode (ou une classe) à la fois final et abstract.

N’oubliez pas, les modificateurs d’accès et les spécificateurs optionnels peuvent être listés dans n’importe quel ordre, mais une fois que le type de retour est spécifié, le reste des parties de la méthode sont écrites dans un ordre spécifique: nom, liste de paramètres, liste d’exceptions, corps.

Concentrez-vous sur la syntaxe pour l’instant. Voyez-vous pourquoi ces méthodes compilent ou ne compilent pas?

public class Exercice {
    public void velo1() {}
    public final void velo2() {}
    public static final void velo3() {}
    public final static void velo4() {}
    public modifier void velo5() {} // NE COMPILE PAS
    public void final velo6() {} // NE COMPILE PAS
    final public void velo7() {}
}

La méthode velo1() est une déclaration valide sans spécificateur optionnel. C’est acceptable—c’est optionnel, après tout. La méthode velo2() est une déclaration valide, avec final comme spécificateur optionnel. Les méthodes velo3() et velo4() sont des déclarations valides avec à la fois final et static comme spécificateurs optionnels. L’ordre de ces deux mots-clés n’a pas d’importance. La méthode velo5() ne compile pas car modifier n’est pas un spécificateur optionnel valide. La méthode velo6() ne compile pas car le spécificateur optionnel est après le type de retour.

La méthode velo7() compile. Java permet aux spécificateurs optionnels d’apparaître avant le modificateur d’accès. C’est un cas étrange et pas un que vous devez connaître.

Type de Retour

L’élément suivant dans une déclaration de méthode est le type de retour. Il doit apparaître après tous les modificateurs d’accès ou spécificateurs optionnels et avant le nom de la méthode. Le type de retour peut être un type Java réel tel que String ou int. S’il n’y a pas de type de retour, le mot-clé void est utilisé. Ce type de retour spécial vient de la langue anglaise : void signifie sans contenu.

N’oubliez pas qu’une méthode doit avoir un type de retour. Si aucune valeur n’est retournée, le mot-clé void doit être utilisé. Vous ne pouvez pas omettre le type de retour.

Lors de la vérification des types de retour, vous devez également regarder à l’intérieur du corps de la méthode. Les méthodes avec un type de retour autre que void sont obligées d’avoir une instruction return à l’intérieur du corps de la méthode. Cette instruction return doit inclure le primitif ou l’objet à retourner. Les méthodes qui ont un type de retour void sont autorisées à avoir une instruction return sans valeur retournée ou à omettre complètement l’instruction return. Pensez à une instruction return dans une méthode void comme si la méthode disait : “J’ai fini !” et quittait tôt, comme suit :

public void nager(int distance) {
    if(distance <= 0) {
        // Sortir tôt, rien à faire !
        return;
    }
    System.out.print("Le poisson nage " + distance + " mètres");
}

Prêt pour quelques exemples ? Pouvez-vous expliquer pourquoi ces méthodes compilent ou non ?

public class Randonnee {
    public void marcher1() {}
    public void marcher2() { return; }
    public String marcher3() { return ""; }
    public String marcher4() {} // NE COMPILE PAS
    public marcher5() {} // NE COMPILE PAS
    public String int marcher6() { } // NE COMPILE PAS
    String marcher7(int a) { // NE COMPILE PAS
        if (1 < 2) return "orange";
    }
}

Puisque le type de retour de la méthode marcher1() est void, l’instruction return est optionnelle. La méthode marcher2() montre l’instruction return optionnelle qui ne retourne correctement rien. La méthode marcher3() est une déclaration valide avec un type de retour String et une instruction return qui retourne une chaîne. La méthode marcher4() ne compile pas car l’instruction return est manquante. La méthode marcher5() ne compile pas car le type de retour est manquant. La méthode marcher6() ne compile pas car elle tente d’utiliser deux types de retour. Vous n’avez droit qu’à un seul type de retour.

La méthode marcher7() est un peu délicate. Il y a une instruction return, mais elle n’est pas toujours exécutée. Même si 1 est toujours inférieur à 2, le compilateur n’évaluera pas complètement l’instruction if et nécessite une instruction return si cette condition est fausse. Qu’en est-il de cette version modifiée?

String marcher8(int a) {
    if (1 < 2) return "orange";
    return "pomme"; // AVERTISSEMENT DU COMPILATEUR
}

Le code compile, bien que le compilateur produira un avertissement concernant le code inaccessible (ou code mort). Cela signifie que le compilateur était assez intelligent pour réaliser que vous avez écrit du code qui ne peut pas être atteint.

Lors du retour d’une valeur, celle-ci doit être assignable au type de retour. Pouvez-vous repérer ce qui ne va pas avec deux de ces exemples?

public class Mesure {
    int getHauteur1() {
        int temp = 9;
        return temp;
    }
    int getHauteur2() {
        int temp = 9L; // NE COMPILE PAS
        return temp;
    }
    int getHauteur3() {
        long temp = 9L;
        return temp; // NE COMPILE PAS
    }
}

La méthode getHauteur2() ne compile pas car vous ne pouvez pas assigner un long à un int. La méthode getHauteur3() ne compile pas car vous ne pouvez pas retourner une valeur long comme un int. Si ce n’était pas clair pour vous, vous devriez revenir au Chapitre 2, “Opérateurs”, et relire les sections sur les types numériques et le casting.

Nom de Méthode

Les noms de méthode suivent les mêmes règles que nous avons pratiquées avec les noms de variables au Chapitre 1, “Blocs de Construction”. Pour rappel, un identifiant ne peut contenir que des lettres, des chiffres, des symboles de devise ou _. De plus, le premier caractère n’est pas autorisé à être un chiffre, et les mots réservés ne sont pas autorisés. Enfin, le caractère underscore simple n’est pas autorisé.

Par convention, les méthodes commencent par une lettre minuscule, mais ce n’est pas obligatoire. Puisqu’il s’agit d’une révision du Chapitre 1, nous pouvons passer directement à la pratique avec quelques exemples:

public class SortieALaPlage {
    public void jogger1() {}
    public void 2jogger() {} // NE COMPILE PAS
    public jogger3 void() {} // NE COMPILE PAS
    public void Jogger_$() {}
    public _() {} // NE COMPILE PAS
    public void() {} // NE COMPILE PAS
}

La méthode jogger1() est une déclaration valide avec un nom traditionnel. La méthode 2jogger() ne compile pas car les identifiants ne sont pas autorisés à commencer par des chiffres. La méthode jogger3 ne compile pas car le nom de la méthode est avant le type de retour. La méthode Jogger_$() est une déclaration valide. Bien qu’il ne soit certainement pas de bonne pratique de commencer un nom de méthode par une majuscule et de terminer par une ponctuation, c’est légal. La méthode _ n’est pas autorisée car elle consiste en un seul underscore. La dernière ligne de code ne compile pas car le nom de la méthode est manquant.

Liste de Paramètres

Bien que la liste de paramètres soit requise, elle n’a pas besoin de contenir de paramètres. Cela signifie que vous pouvez simplement avoir une paire de parenthèses vides après le nom de la méthode, comme suit:

public class Dormir {
    void sieste() {}
}

Si vous avez plusieurs paramètres, vous les séparez par une virgule. Il y a encore quelques règles pour la liste de paramètres que vous verrez lorsque nous couvrirons les varargs prochainement. Pour l’instant, pratiquons en examinant les déclarations de méthode avec des paramètres “réguliers”:

public class EducationPhysique {
    public void courir1() {}
    public void courir2 {} // NE COMPILE PAS
    public void courir3(int a) {}
    public void courir4(int a; int b) {} // NE COMPILE PAS
    public void courir5(int a, int b) {}
}

La méthode courir1() est une déclaration valide sans paramètres. La méthode courir2() ne compile pas car il manque les parenthèses autour de la liste de paramètres. La méthode courir3() est une déclaration valide avec un paramètre. La méthode courir4() ne compile pas car les paramètres sont séparés par un point-virgule plutôt qu’une virgule. Les points-virgules sont pour séparer les instructions, pas pour les listes de paramètres. La méthode courir5() est une déclaration valide avec deux paramètres.

Signature de Méthode

Une signature de méthode, composée du nom de la méthode et de la liste de paramètres, est ce que Java utilise pour déterminer de façon unique quelle méthode vous essayez d’appeler. Une fois qu’il détermine quelle méthode vous essayez d’appeler, il détermine ensuite si l’appel est autorisé. Par exemple, tenter d’accéder à une méthode private en dehors de la classe ou assigner la valeur de retour d’une méthode void à une variable int entraîne des erreurs de compilation. Aucune de ces erreurs de compilation n’est liée à la signature de la méthode, cependant.

Il est important de noter que les noms des paramètres dans la signature de la méthode ne sont pas utilisés comme partie d’une signature de méthode. La liste de paramètres concerne les types de paramètres et leur ordre. Par exemple, les deux méthodes suivantes ont exactement la même signature:

public class Voyage {
    public void visiterZoo(String nom, int tempsDAttente) {}
    public void visiterZoo(String attraction, int pluie) {} // NE COMPILE PAS
}

Malgré des noms de paramètres différents, ces deux méthodes ont la même signature et ne peuvent pas être déclarées dans la même classe. Changer l’ordre des types de paramètres permet à la méthode de compiler, cependant:

public class Voyage {
    public void visiterZoo(String nom, int tempsDAttente) {}
    public void visiterZoo(int pluie, String attraction) {}
}

Liste d’Exceptions

En Java, le code peut indiquer que quelque chose s’est mal passé en lançant une exception. Nous couvrons cela au Chapitre 11, “Exceptions et Localisation”. Pour l’instant, vous devez juste savoir que c’est optionnel et où cela se place dans la déclaration de méthode si présent. Par exemple, InterruptedException est un type d’Exception. Vous pouvez lister autant de types d’exceptions que vous voulez dans cette clause, séparés par des virgules. Voici un exemple:

public class MonorailZoo {
    public void zeroExceptions() {}
    public void oneException() throws IllegalArgumentException {}
    public void twoExceptions() throws 
        IllegalArgumentException, InterruptedException {}
}

Bien que la liste d’exceptions soit optionnelle, elle peut être requise par le compilateur, selon ce qui apparaît à l’intérieur du corps de la méthode. Vous en apprendrez plus à ce sujet, ainsi que sur la façon dont les méthodes qui les appellent peuvent être requises pour gérer ces déclarations d’exception, au Chapitre 11.

Corps de Méthode

La dernière partie d’une déclaration de méthode est le corps de la méthode. Un corps de méthode est simplement un bloc de code. Il a des accolades qui contiennent zéro ou plusieurs instructions Java. Nous avons passé plusieurs chapitres à examiner les instructions Java à ce stade, vous devriez donc trouver facile de comprendre pourquoi celles-ci compilent ou non:

public class Oiseau {
    public void voler1() {}
    public void voler2() // NE COMPILE PAS
    public void voler3(int a) { int nom = 5; }
}

La méthode voler1() est une déclaration valide avec un corps de méthode vide. La méthode voler2() ne compile pas car il manque les accolades autour du corps de méthode vide. Les méthodes sont obligées d’avoir un corps sauf si elles sont déclarées abstract. Nous couvrons les méthodes abstract au Chapitre 6, “Conception de Classe”. La méthode voler3() est une déclaration valide avec une instruction dans le corps de la méthode.

Félicitations ! Vous avez réussi à passer en revue les bases de l’identification des déclarations de méthode correctes et incorrectes. Maintenant, vous pouvez approfondir les détails.