Pour répondre à la question sur le titre, en général, les méthodes de Java doit pas être statique par défaut. Java est un langage orienté-objet.
Cependant, ce que vous dites est un peu différent. Vous parler plus précisément des méthodes d'assistance.
Dans le cas de méthodes d'aide qui vient de prendre les valeurs que les paramètres et retourner une valeur, sans accéder à l'état, ils doivent être statique. Privé et statique. Permettez-moi de le souligner:
Les méthodes d'aide qui ne sont pas en état d'accès doit être statique.
1. Avantage majeur: le code est plus expressif.
Faire de ces méthodes statiques a au moins un avantage majeur: vous rendre totalement explicite dans le code de la méthode n'a pas besoin de connaître l'état de l'instance.
Le code parle de lui-même. Les choses deviennent plus évidents pour d'autres personnes qui vont lire votre code, et de même pour vous à un certain point dans l'avenir.
2. Un autre avantage: le code peut être plus simple de raisonner sur.
Si vous assurez-vous que la méthode ne dépend pas de l'externe ou de l'état global, alors que c'est une fonction pure, c'est à dire, une fonction au sens mathématique: pour la même entrée, vous pouvez être certain d'obtenir toujours le même résultat.
3. L'optimisation des avantages
Si la méthode est statique et est une fonction pure, dans certains cas, il pourrait être memoized pour obtenir des gains de performance (dans le changement de l'utilisation de plus de mémoire).
4. Bytecode-les différences de niveau de
Au niveau du bytecode, si vous déclarez l'aide de la méthode comme une méthode d'instance ou comme une méthode statique, vous obtiendrez deux choses complètement différentes.
Pour aider à rendre cette section plus facile à comprendre, prenons un exemple:
public class App {
public static void main(String[] args) {
WithoutStaticMethods without = new WithoutStaticMethods();
without.setValue(1);
without.calculate();
WithStaticMethods with = new WithStaticMethods();
with.setValue(1);
with.calculate();
}
}
class WithoutStaticMethods {
private int value;
private int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
class WithStaticMethods {
private int value;
private static int helper(int a, int b) {
return a * b + 1;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public int calculate() {
return helper(value, 2 * value);
}
}
Les lignes qui nous intéressent sont les appels à l' helper(...)
sur les classes WithoutStaticMethods
et WithStaticMethods
.
Sans méthodes statiques
Dans le premier cas, sans méthodes statiques, lorsque vous appelez la méthode d'assistance à la JVM doit pousser la référence à l'instance de la transmettre à l' invokespecial
. Jetez un coup d'oeil au code de l' calculate()
méthode:
0 aload_0
1 aload_0
2 getfield #2 <app/WithoutStaticMethods.value>
5 iconst_2
6 aload_0
7 getfield #2 <app/WithoutStaticMethods.value>
10 imul
11 invokespecial #3 <app/WithoutStaticMethods.helper>
14 ireturn
L'instruction à 0 (ou 1), en aload_0
, va charger la référence à l'instance sur la pile, et il sera utilisé plus tard par invokespecial
. Cette instruction va mettre cette valeur en tant que premier paramètre de l' helper(...)
de la fonction, et il n'est jamais utilisé, comme nous pouvons le voir ici:
0 iload_1
1 iload_2
2 imul
3 iconst_1
4 iadd
5 ireturn
Voir il n'y a pas d' iload_0
? Il a été chargé inutilement.
Avec des méthodes statiques
Maintenant, si vous déclarez la méthode d'assistance, statique, puis l' calculate()
méthode ressemblera à:
0 aload_0
1 getfield #2 <app/WithStaticMethods.value>
4 iconst_2
5 aload_0
6 getfield #2 <app/WithStaticMethods.value>
9 imul
10 invokestatic #3 <app/WithStaticMethods.helper>
13 ireturn
Les différences sont:
- il y a un moins d'
aload_0
enseignement
- la méthode d'assistance est maintenant appelé avec
invokestatic
Ainsi, le code de la fonction d'assistance est également un peu différent: il n'y a pas d' this
comme premier paramètre, les paramètres sont à des positions 0 et 1, comme on peut le voir ici:
0 iload_0
1 iload_1
2 imul
3 iconst_1
4 iadd
5 ireturn
Conclusion
De la conception du code de l'angle, il fait beaucoup plus de sens pour déclarer l'aide de la méthode statique: le code parle de lui-même, il contient les informations les plus utiles. Il affirme qu'il n'a pas besoin de l'état de l'instance de travail.
Au niveau du bytecode, il est beaucoup plus claire de ce qui se passe, et il n'est pas inutile de code (que, bien que je crois que l'équipe n'a aucun moyen de l'optimiser, n'entraînerait pas de façon significative les performances de coût).