J'essaye de réutiliser mon constructeur comme ceci:
public final long x;
public final long y;
public final int level;
private final int hash;
public final Point tileCenter;
public TileCoordinate(long x, long y, int level) {
this.x = x;
this.y = y;
this.level = level;
this.hash = Objects.hash(x, y, level);
this.tileCenter = getTileCenter();
}
public TileCoordinate(String key) {
String[] bits = key.split("-");
// this.level = Integer.parseInt(bits[0]);
// this.x = Long.parseLong(bits[1]);
// this.y = Long.parseLong(bits[2]);
this(Long.parseInt(bits[0]),Long.parseLong(bits[1]),Integer.parseLong(bits[2]));
this.hash = Objects.hash(x, y, level);
this.tileCenter = getTileCenter();
}
Puisque je ne veux pas écrire this (Integer.parseInt (key.split ("-") [0 ]), Long.parseLong (key.split ("-") [1]), Long.parseLong (key.split ("-"))); , quelles sont mes options?
3 Réponses :
Il semble que vous ne faites que cette ligne String [] bits = key.split ("-"); pour éviter d'avoir à l'appeler 3 fois dans l'appel du constructeur différé à this () , qui, s'il existe, doit être la première instruction d'un constructeur.
Au lieu de déléguer à un constructeur pour l'affectation réelle du champ, déléguez à un private méthode qui gère les attributions de champ.
public TileCoordinate(String key) {
String[] bits = key.split("-");
init(Long.parseInt(bits[0]),Long.parseLong(bits[1]),Integer.parseInt(bits[2]));
this.hash = Objects.hash(x, y, level);
this.tileCenter = getTileCenter();
}
private void init(long x, long y, int level) {
// assign to fields here
}
Assurez-vous qu'il est privé afin qu'il ne puisse pas être remplacé, où fuite ce code > deviendrait un problème.
Vous pouvez également vérifier que bits contient 3 éléments avant de continuer.
Mais les champs sont définitifs, j'ai oublié de dire ça
Eh bien, maintenant que vous avez révélé que vos champs sont définitifs , cela ne fonctionnera pas. Dans ce cas, une méthode d'usine serait la voie à suivre.
L'appel à this () ou super () doit être la première instruction du constructeur. Une façon de résoudre ce problème serait de convertir le deuxième constructeur en une Méthode d'usine :
public static TileCoordinate parseTitleCoordinate(String key) {
String[] bits = key.split("-");
long x = Long.parseLong(bits[0]);
long y = Long.parseLong(bits[1]);
long level = Long.parseLong(bits[2]);
return new TitleCoordinate(x, y, level);
}
Cela permettrait de conserver les champs final.
Pourquoi super () est-il nécessaire?
Pourrait surcharger une méthode init:
public TileCoordinate(long x, long y, int level) {
init(x, y, level);
}
public TileCoordinate(String key) {
init(key);
}
private void init(String key) {
String[] bits = key.split("-");
init(Long.parseLong(bits[0]),
Long.parseLong(bits[1]),
Integer.parseInt(bits[2]));
}
private void init(long x, long y, int level) {
this.setX(x);
this.setY(y);
this.setLevel(level);
}
Cela maintient une seule responsabilité. Seule la 2ème méthode init appelle les setters, le reste délègue.
Pourriez-vous clarifier ce que signifie
puisque je ne veux pas répéter key.split pour chaque paramètre? Vous n'avez qu'un seul paramètre correct?non, je veux dire que je ne veux pas écrire
ceci (Integer.parseInt (key.split ("-") [0]), Long.parseLong (key. split ("-") [1]), Long. parseLong (key.split ( "-")));Est-ce parce que l'appel à
thisdoit être la première instruction d'un constructeur, s'il existe?oui c'est le problème
Que diriez-vous plutôt d'une méthode d'usine statique?
Je suppose que vous pourriez avoir une méthode
setParam ()pour faire exactement ce que fait votre constructeur sans qu'il soit un constructeur.