Question

sont Java méthodes finales automatiquement affichées?

De nombreux livres dit oui beaucoup de livres dit pas !!!

Était-ce utile?

La solution

Question intéressante, m'a incité à examiner de plus près. 2 remarques intéressantes que je trouve -

  

Contrairement à l'implication d'un grand nombre   trucs et astuces, les méthodes déclarées comme définitive ne peut pas   être en toute sécurité inline par le compilateur,   parce que la méthode pourrait avoir un   déclaration non-finale lors de l'exécution.

     

Pour voir pourquoi, supposons que les regards du compilateur   à la classe A et de classe B, et   la sous-sous-classe C et voit une méthode finale   en A qui il inline en C. Mais   lors de l'exécution des versions chargées A   et B sont différentes et le procédé est   non finale A et B. de substitution dans   Ensuite, C utilise le inline incorrectement   version. T

Et, un peu plus autoritairement, d'un soleil livre blanc, l'écriture que les méthodes peuvent rester virtuelle,

  

Parce que la machine virtuelle Java HotSpot peut inline automatiquement la grande majorité des invocations de méthode virtuelle, cette pénalité de performance est considérablement réduit, et dans de nombreux cas, tout à fait éliminé.

Voici un plus de référence directe sur le mécanisme.

Autres conseils

Inlining des méthodes est effectuée par le compilateur JIT, pas javac.

compilateurs modernes JIT (y compris Hotspot) peuvent souvent inline même des méthodes non-finales «défaisant » l'optimisation appropriée si nécessaire. Ils sont essentiellement effroyablement intelligent.

En bref: cela dépend entièrement de la machine virtuelle. À mon avis, vous devriez faire vos méthodes finale ou non en fonction de ce produit le code plus propre plutôt que la performance. Personnellement, je suis un fan de « la conception de l'héritage ou l'interdire », mais c'est une autre discussion:)

Si vous voulez dire « ils s'inline lors de la compilation », alors non, ils ne seront pas.

Cependant, les champs statiques finales peuvent parfois être inline par le compilateur, par exemple des primitives et des chaînes.

final est plus sur l'ajout sémantique à une conception que de dire à un compilateur ou VM inline quelque chose. Machines virtuelles moderne en ligne beaucoup plus que les méthodes finales seuls, donc ce n'est pas une bonne raison d'utiliser final ou essayer de prédire trop sur les optimisations d'exécution.

Je pense que cela dépend de la mise en œuvre qui JVM que vous utilisez sur. Certes, ce qui rend une dernière méthode permet au compilateur la possibilité de faire une telle tweak de mise en œuvre. Mais si elle fait ou ne peut également dépendre d'autres facteurs - par exemple si sa méthode énorme, etc .....

La décision de Hotspot si inline est incroyablement complexe, dépend d'une multitude de considérations, mais je ne pense pas que si la méthode est marquée « finale » est l'un d'entre eux. La raison en est qu'il est déjà au courant du fait que plusieurs mises en œuvre de cette méthode ont été chargés dans la machine virtuelle, il est donc indifférent de savoir également si ces mises en œuvre sont autorisés.

Dans tous les cas, il va seulement être très petites et simples méthodes qui se, et non enligne même tous ceux-ci.

Jon dit le inline est fait (le cas échéant) par le compilateur JIT pas au niveau de la génération de bytecode. Notez également que inline peut parfois entraîner une dégradation des performances car il pourrait créer une situation où le même code est présent plusieurs fois dans le cache de cpu, l1 supprimant l'espace pour d'autres codes. cache L1 misses peuvent influer sur le rendement plus d'un saut à une fonction en cache.

Constantes (aka var statique finale) sont inline à la place.

Voir ce pour vérifier

public class InlineTest {
    final static int add(int x, int y) {
        return x + y;
    } 
}


public class Main {

        static final int DIVISOR = 7;

        static void main(String[] args){
            final int a = new Integer(args[0]);
            final int b = new Integer(args[1]);

            if (InlineTest.add(a, b) % DIVISOR == 0)
                System.exit(InlineTest.add(a, b));

            System.out.print("The sum is " + InlineTest.add(a, b));

        }
}

Cela se traduit par:

 0 new #2 <java/lang/Integer>
 3 dup
 4 aload_0
 5 iconst_0
 6 aaload
 7 invokespecial #3 <java/lang/Integer/<init>(Ljava/lang/String;)V>
10 invokevirtual #4 <java/lang/Integer/intValue()I>
13 istore_1
14 new #2 <java/lang/Integer>
17 dup
18 aload_0
19 iconst_1
20 aaload
21 invokespecial #3 <java/lang/Integer/<init>(Ljava/lang/String;)V>
24 invokevirtual #4 <java/lang/Integer/intValue()I>
27 istore_2
28 iload_1
29 iload_2
30 invokestatic #5 <com/gamasoft/InlineTest/add(II)I>
33 bipush 7
35 irem
36 ifne 47 (+11)
39 iload_1
40 iload_2
41 invokestatic #5 <com/gamasoft/InlineTest/add(II)I>
44 invokestatic #7 <java/lang/System/exit(I)V>
47 getstatic #8 <java/lang/System/out Ljava/io/PrintStream;>
50 new #9 <java/lang/StringBuilder>
53 dup
54 invokespecial #10 <java/lang/StringBuilder/<init>()V>
57 ldc #11 <The sum is >
59 invokevirtual #12 <java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;>
62 iload_1
63 iload_2
64 invokestatic #5 <com/gamasoft/InlineTest/add(II)I>
67 invokevirtual #13 <java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;>
70 invokevirtual #14 <java/lang/StringBuilder/toString()Ljava/lang/String;>
73 invokevirtual #15 <java/io/PrintStream/print(Ljava/lang/String;)V>
76 return

Vous pouvez voir que la fonction statique InlineTest.add a été appelé à plusieurs reprises avec invokestatic

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top