La modification finale champs en Java

Nous allons commencer avec un simple cas de test:

import java.lang.reflect.Field;

public class Test {
  private final int primitiveInt = 42;
  private final Integer wrappedInt = 42;
  private final String stringValue = "42";

  public int getPrimitiveInt()   { return this.primitiveInt; }
  public int getWrappedInt()     { return this.wrappedInt; }
  public String getStringValue() { return this.stringValue; }

  public void changeField(String name, Object value) throws IllegalAccessException, NoSuchFieldException {
    Field field = Test.class.getDeclaredField(name);
    field.setAccessible(true);
    field.set(this, value);
    System.out.println("reflection: " + name + " = " + field.get(this));
  }

  public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
    Test test = new Test();

    test.changeField("primitiveInt", 84);
    System.out.println("direct: primitiveInt = " + test.getPrimitiveInt());

    test.changeField("wrappedInt", 84);
    System.out.println("direct: wrappedInt = " + test.getWrappedInt());

    test.changeField("stringValue", "84");
    System.out.println("direct: stringValue = " + test.getStringValue());
  }
}

Quiconque le soin de deviner ce qui va être imprimé en sortie (indiqué en bas pour ne pas gâcher la surprise immédiatement).

Les questions sont:

  1. Pourquoi primitive et enveloppé entier se comporter différemment?
  2. Pourquoi ne réfléchissant vs un accès direct retour des résultats différents?
  3. L'un des fléaux qui m'a le plus - pourquoi Chaîne se comportent comme des primitifs int et non pas comme Integer?

Résultats (java 1.5):

reflection: primitiveInt = 84
direct: primitiveInt = 42
reflection: wrappedInt = 84
direct: wrappedInt = 84
reflection: stringValue = 84
direct: stringValue = 42
  • cela peut étroitement liés à la compilateur.
InformationsquelleAutor ChssPly76 | 2009-10-23