Sur les derniers mots-clés statiques en Java

Selon le tutoriel :

Le modificateur static , associé au modificateur final , est également utilisé pour définir des constantes. Le final modificateur indique que la valeur de ce champ ne peut pas changer.

Je serais d’accord avec cela seulement si les types impliqués étaient primitifs. Avec les types de référence, par exemple une instance de classe Point2D dont les atsortingbuts de position ne sont pas final (c.-à-d. Point2D nous pouvons changer sa position), les atsortingbuts de ce type de variables tels que public static final Point2D A = new Point2D(x,y); pourrait encore être changé. Est-ce vrai?

Oui, cela peut être changé. Seules les références ne peuvent pas être modifiées, mais ses champs internes peuvent l’être. Le code suivant le montre:

 public class Final { static final Point p = new Point(); public static void main(Ssortingng[] args) { p = new Point(); // Fails pb = 10; // OK pa = 20; // Fails } } class Point { static final int a = 10; static int b = 20; } 

Groovy (un autre langage JVM ) a une annotation appelée @Immutable , qui bloque le passage à un état interne d’un object après sa construction.

Correct, il peut encore être changé. La “statique finale”, dans ce cas, fait référence à la référence elle-même, qui ne peut pas être modifiée. Toutefois, si l’object auquel il fait référence est modifiable, l’object qu’il référence peut être modifié.

Un object immuable, tel qu’une chaîne, sera une constante.

 public static final Point2D A = new Point2D(x,y); 

Ici, la référence A est finale et non les valeurs à l’intérieur de la classe Point2D .

Vous ne pouvez pas le faire après avoir défini une finale statique:

 //somewhere else in code A = new Point2D(x1,y1); 

C’est vrai. Le modificateur final n’est pas transitif de quelque manière que ce soit.

Cela signifie seulement que la référence ne changera pas. Le contenu de la référence (les champs de l’object) peut changer avec le temps.

final statique public Point2D A = nouveau Point2D (x, y); pourrait encore être changé. Est-ce vrai?

La référence de A n’a pas pu être modifiée, mais la valeur réelle de son object associé peut être modifiée si les atsortingbuts ne sont pas définitifs.

 class Point2D{ private int x; private int y;  } class Constant{ Public static final Point2D A = new Point2D(1,2); public static void main(Ssortingng[] args){ A.setX(10); // this will work A = new Point2D(10,20);// this will not work } } 

Point2D's atsortingbuts Point2D's sont définitifs, la class Point2D serait immutable .

ou vous pouvez envoyer l’object clone-able.

Comme –

  private static final Point2D A = new Point2D(x,y); public static getA(){ return A.clone(); } 

La référence au point ( A dans votre cas) ne peut pas changer. Seul l’état de l’object peut changer. Vous ne pouvez donc pas créer un nouveau Point2D et l’assigner à la variable.

Seule la référence est définitive, l’object référencé peut être modifié (sauf s’il s’agit d’un object immuable, comme Integer ou similaire). Donc oui, ce n’est que constant pour une valeur donnée de “constant”.

Oui.

Bien entendu, vous pouvez également modifier la valeur du champ final ultérieurement, comme décrit ailleurs .

Vous pouvez trouver une question très similaire ici avec une assez bonne explication:

ICI: Pourquoi l’object final peut-il être modifié?

Au fait, j’ai commencé à penser au mécanisme de reflection ….

en théorie … je crois que vous pouvez posséder une instance de classe .. puis obtenir les membres de la classe, trouver l’instance actuelle et vérifier qu’elle est finale ….

Je ne l’ai pas vérifié et je ne sais même pas si c’est possible – c’est juste une idée (peut-être?)

dans

 public class Final { static final Point p = new Point(); public static void main(Ssortingng[] args) throws MyImmutableException { p = new Point(); // Fails p.setB(10); // OK p.setA(20); // Fails - throws MyImmutableException } } public class Point() { int a = 10; int b = 20; public setA(int a) { this.a = a; } public setB(int b) throws MyImmutableException { detectIsFinal() this.b = b; } private void detectIsFinal() throws MyImmutableException { int mod = this.getClass().getModifiers() if (Modifier.isFinal(mod)) { throw new MyImmutableException(); } } } public class MyImmutableException extends Exception { public MyImmutableException() {super(); } } 

Je pensais à ce que tu peux faire d’autre … encore une fois, c’est juste un !!!!!!!!! PSEUDOCODE !!! Je ne sais pas si ça va marcher: P

Peut-être que quelqu’un avec des connaissances en annotations sera inspiré et le fera fonctionner. Malheureusement, je n’ai pas plus de temps cette semaine. Peut-être que plus tard j’essaierai de faire un POC.

 public class Final { @Immutable static final Point p = new Point(); public static void main(Ssortingng[] args) { p = new Point(); // Fails p.setB(10); // Fails p.setA(20); // OK } } public class Point() { int a = 10; @ImmutableOnThisInstance int b = 20; @DetectIsImmutable public setA(int a) { this.a = a; } @DetectIsImmutable public setB(int b) { this.b = b; } } class Immutable { ????????????????? } class DetectIsImmutable { /** * Just a pseudocode - I don't know how to work with ANNOTATIONS :) :) :) * SORRY :) * @throws MyImmutableException */ private void detectMethod() throws MyImmutableException { Immutable instance = CLASS_THAT_IS_ANNOTATED.getClass().getAnnotation(Immutable.class) if (instance != null) { // get parent Method invocation name (from stacktrace list) Ssortingng methodName = .............; if (methodName.startsWith("set")) { // check id we have variable with this settername Ssortingng fieldName = ...; // cut "set" get rest of it, make first letterSmall // find this field in object fields Field f = this.getClass().getDeclaredField(fieldName); if (f.getAnnotation(ImmutableOnThisInstance.class) != null) { throw MyImmutableException(); } } } } } 

C’est toujours vrai.

Il y a un moyen par lequel la demande que vous citez est vraie. static final décrit une variable , et il est vrai que cette variable ne peut pas changer et est donc une constante. La variable est un pointeur sur un object et cet object peut changer. Mais cela n’empêche pas la variable d’être une constante.

C’est un moyen moins puissant d’être vrai avec const en C ++, mais c’est quelque chose.

Oui tu as raison. La référence ne peut pas être modifiée, mais l’object référencé peut l’être. Quelque chose comme cela est parfaitement légal:

 public static final List someList = new ArrayList(); // ... someList.add(someThing); // <-- this would be illegal if the referenced object was also constant 

Vous pouvez modifier les propriétés de Point2D, mais ne pas en créer une nouvelle.

Je devrais également mentionner que Point2D est abstrait, vous devez donc créer une instance d’une classe enfant qui l’étend.

Comme d’autres ont déjà mentionné, c’est la référence à votre object Point2D qui est statique finale, pas les atsortingbuts x et y. Si vous voulez vous assurer que vous ne pouvez pas modifier la position d’un object Point2D, vous devez définir les atsortingbuts x et y statiques et finaux (initialisés) dans la classe Point2D.

 static final Point2D A = new Point2D(x,y); 

Tout ce qu’il dit, c’est que la référence à la classe Point2D ne peut pas être modifiée.

  _____________ | | A----------|--->(x,Y) | | | |_____________|Heap 

Donc, vous ne pouvez pas modifier A en pointant sur un object différent, mais vous pouvez bien sûr modifier la valeur de (x, y) ou le contenu de l’object Point

Si vous voulez que votre object soit aussi constant, vous devrez rendre l’object Point immuable.

Lorsqu’une variable de référence est déclarée comme finale, vous ne pouvez pas lui affecter un nouvel object une fois qu’il fait référence à un object. Mais, vous pouvez changer l’état d’un object vers lequel la variable de référence finale pointe. Regardez l’exemple ci-dessous.

 class A { int i = 10; } public class UseOfFinalKeyword { public static void main(Ssortingng[] args) { final A a = new A(); //final reference variable ai = 50; //you can change the state of an object to which final reference variable is pointing a = new A(); //comstack time error //you can't re-assign a new object to final reference variable } } 

Pour plus d’informations, suivez le lien: mot clé final en java