Java : se code comme une classe, s'utilise comme un entier

Par:
fredericmazue

ven, 09/05/2014 - 18:46

Tel est le sous-titre d'un très intéressant billet écrit par 3 ingénieurs d'Oracle : John Rose, Brian Goetz, and Guy Steele

Ce billet est une proposition pour étendre le langage Java d'un nouveau type : le type Value. La proposition part du constat que de nombreux objets ne sont jamais transtypés lors de leur existence dans un programme, pas plus qu'il n'est fait appel au polymorphisme, ou même que leur état change. Pourtant ces objets sont alloués sur le tas et conservent des informations utilisées pour la mutabilité, le transtypage, etc. Ces objets conservent également un ou plusieurs pointeurs pointant sur eux-mêmes,. Tout cela tout à fait inutilement, ce qui est coûteux en terme de ressources mémoire et de temps d'exécution.

Le billet prend pour exemple une classique classe Point :

final class Point {
    public final int x;
   public final int y;

    public Point(int x, int y) {
       this.x = x;
       this.y = y;
   }

}

et montre le coût d'une telle classe, bien que non mutable, en terme d'empreinte mémoire au sein de la JVM. Coût qui est encore plus élevé si des instances de cette classe sont rangées dans un tableau.

Avec une Value type nous aurions alors ceci :

final __ByValue class Point {
   public final int x;
   public final int y; 

    public Point(int x, int y) {
       this.x = x;
       this.y = y;
   }

 

    public boolean equals(Point that) {
       return this.x == that.x && this.y == that.y;
   }
}

 

et dans ce cas , grâce au simple mot clé __ByValue, notre classe Point serait manipulée comme un type primitif. Ainsi la JVM n'allouerait que de quoi stocker x et y pour une instance de cette classe, et un tableau d'instance de cette classe serait un tableau de valeurs x et y, plutôt qu'un tableau de références.

Se code comme une classe, s'utilise comme un entier

Toujours selon le billet, cela pourrait se présenter comme ceci :

static Point origin = __MakeValue(0, 0);

static String stringValueOf(Point p) {
   return "Point("+p.x+","+p.y+")";
}

static Point displace(Point p, int dx, int dy) {
   if (dx == 0 && dy == 0)
     return p;

   Point p2 = __MakeValue(p.x + dx, p.y + dy);
   assert(!p.equals(p2));

    return p2;
}

Dans cet exemple un point est aussi bien un champ qu'un argument, une variable locale ou une valeur de retour.