Puisqu'il s'agit de constantes, autant qu'elles soient statiques pour ne pas les redéfinir à chaque fois que la commande est tapée ?
C'est un peu plus compliqué que cela, prenons un premier exemple :
Java:
int f() {
final Random random = new Random();
final int x = random.nextInt(6);
final int y = x + 5;
final int z = x - 2;
return y * z;
}
Ici, « x », « y », « z » et le produit des deux derniers sont tous quatre constants pendant toute leur durée de vie, c'est-à-dire de leur création à la fin d'exécution de la fonction « f ».
La meilleure chose que le compilateur puisse faire, c'est zigouiller les variables intermédiaires :
Java:
int f() {
final int x = new Random().nextInt(6);
return (x + 5) * (x - 2);
}
Ce qui évite au processeur de faire des allers-retours dans la mémoire vive pour stocker et lire « y » et « z » alors qu'il pourrait tout faire chez lui et simplement renvoyer uniquement le résultat final.
Maintenant, deuxième exemple :
Java:
boolean g(int 六) {
final int 三 = 3;
final int 九 = 三 * 三;
return (三 + 六) == 九;
}
Les deux variables « 三 » et « 九 » sont constantes pendant toute la durée de l'univers, tu peux donc les transformer en littéraux :
Java:
boolean g(int 六) {
return (3 + 六) == 9;
}
Donc, nos deux fonctions après simplification :
Java:
int f() {
final int x = new Random().nextInt(6);
// développer nous ferait faire faire plus d'opérations, donc gardons la forme factorisée
return (x + 5) * (x - 2);
}
boolean g(int 六) {
return 六 == 6;
}
Dans les deux cas nous sommes partis d'un nombre constant, avons définis d'autres variables constantes intermédiaires qui ont disparue, or dans le premier cas, il nous reste la constante initiale « x ».
Où est donc passé notre zigouillage ?
Et bien la différence fondamentale est que :
- Dans notre premier cas, la constante « x » subit une affectation.
- Dans notre second cas, la constante « 三 » est définie comme étant une égalité mathématique.
Je rappelle que
a et
b sont égaux entre eux si et seulement si l'on peut remplacer
a par
b et
b par
a.
Dans notre 2e cas, l'on peut écrire « 三 × 三 = 3 × 3 ».
Or dans notre 1er cas, « x + x ≠ random.nextInt(6) + random.nextInt(6) ».
Maintenant, pour en revenir à ta constante statique :
Java:
private static final int RADIUS = 10;
Est-elle constante pour la durée de vie de l'univers ?
Alors en théorie non parce Java est réflexif, mais en pratique oui, j'ai compilé puis décompilé les fonctions pour voir (OpenJDK 17) :
Java:
public class Temp {
private static final float A = 2.72F;
private static final float B = 0.45F;
public Temp() {}
int f() {
Random random = new Random();
int x = random.nextInt(6);
int y = x + 5;
int z = x - 2;
return y * z;
}
boolean g(int 六) {
int 三 = 3;
int 九 = 9;
return 3 + 六 == 9;
}
boolean h(float x) {
// return A * 2 + x == B / 3;
return 5.44F + x == 0.14999999F;
}
}
On peut voir qu'il a un peu optimisé comme un saugrenu, mais Java optimise aussi à l'exécution en transformant le bytecode en code natif, et on peut toujours espérer qu'il optimise mieux un jour.
Donc en théorie il n'y a aucune différence entre mettre la constante dans la classe en
static
, en pratique il optimise comme un pied donc ça te permet d'éviter d'allouer des variables qu'il n'utilisera au final même pas, cependant il y a de fortes chances que le Java de celui qui exécute ton programme refasse une étape d'optimisation par derrière, conclusion la différence est négligeable, c'est comme tu préfères.
J'avais mis la constante dans la fonction par habitude de réduire au plus possible la portée de la variable (si une seule fonction l'utilise, ça ne sert à rien de la rendre accessible pour toutes les autres fonctions), après on peut voir qu'au final il n'a pas enlevé les variables même si elles sont inutilisées, mais bon il a quand même calculé 九 = 9 au lieu de laisser 九 = 3 × 3, et deux allocations de huit octets est un peu cher prix à payer en échange qu'il ne me propose pas des constantes d'autres fonctions dans l'autocomplétion, de plus ça permet d'avoir plusieurs constantes du même nom dans plusieurs fonctions.
P.S.: Les caractères 三, 六 et 九 représentent respectivement les nombres 3, 6 et 9 dans la numération chinoise.