94 votes

Java: Bon moyen d'encapsuler Integer.parseInt ()

J'ai un projet dans lequel nous utilisons souvent Integer.parseInt() pour convertir une Chaîne en un entier (int). Quand quelque chose va mal (par exemple, l' String n'est pas un nombre, mais la lettre a, ou quoi que ce soit) cette méthode lève une exception. Cependant, si je dois gérer les exceptions dans mon code partout, cela commence à être très laid, très rapidement. Je voudrais mettre cela dans une méthode, cependant, je n'ai aucune idée de comment faire pour retourner un propre valeur, afin de montrer que la conversion s'est mal passé.

En C++, je pourrais avoir créé une méthode qui a accepté un pointeur vers un int et laissez la méthode elle-même renvoie true ou false. Cependant, autant que je sache, ce n'est pas possible en Java. Je pourrais aussi créer un objet qui contient un vrai/faux de la variable et la valeur convertie, mais cela ne semble pas idéal. La même chose vaut pour une valeur globale, et cela pourrait me donner quelques ennuis avec le multithreading.

Donc, il y a un moyen propre de faire cela?

146voto

Jon Skeet Points 692016

Vous pouviez retourner un Integer au lieu d'un int, revenant null sur analyser l'échec.

C'est une honte de Java ne fournit pas un moyen de le faire sans qu'il y ait une exception à l'interne, mais - vous pouvez masquer l'exception (par l'attraper et retourner null), mais il pourrait encore être un problème de performances si vous êtes l'analyse des centaines de milliers de bits de données fournies par l'utilisateur.

EDIT: Code pour une telle méthode:

public static Integer tryParse(String text) {
  try {
    return new Integer(text);
  } catch (NumberFormatException e) {
    return null;
  }
}

Notez que je ne suis pas sûr du haut de ma tête ce que cela va faire si text a la valeur null. Vous devriez considérer que - si elle représente un bug (c'est à dire votre code peut très bien passer une valeur non valide, mais ne doit jamais passer la valeur null) puis lancer une exception est approprié; si elle ne représente pas un bug, alors vous devriez probablement juste de retourner la valeur null comme vous le feriez pour toute autre valeur non valide.

37voto

Joachim Sauer Points 133411

Quel comportement attendez-vous quand ce n'est pas un nombre?

Si, par exemple, vous avez souvent une valeur par défaut à utiliser lorsque l'entrée n'est pas un nombre, une méthode telle que celle-ci pourrait être utile:

 public static int parseWithDefault(String number, int defaultVal) {
  try {
    return Integer.parseInt(number);
  } catch (NumberFormatException e) {
    return defaultVal;
  }
}
 

Des méthodes similaires peuvent être écrites pour différents comportements par défaut lorsque l'entrée ne peut pas être analysée.

17voto

Daddyboy Points 806

Pour éviter la gestion des exceptions, utilisez une expression régulière pour vous assurer que vous avez tous les chiffres en premier:

 if(value.matches("\\d+") {
    Integer.parseInt(value);
}
 

4voto

Nikolay Ivanov Points 5117

Peut-être que vous pouvez utiliser quelque chose comme ceci:

 public class Test {
public interface Option<T> {
	T get();

	T getOrElse(T def);

	boolean hasValue();
}

final static class Some<T> implements Option<T> {

	private final T value;

	public Some(T value) {
		this.value = value;
	}

	@Override
	public T get() {
		return value;
	}

	@Override
	public T getOrElse(T def) {
		return value;
	}

	@Override
	public boolean hasValue() {
		return true;
	}
}

final static class None<T> implements Option<T> {

	@Override
	public T get() {
		throw new UnsupportedOperationException();
	}

	@Override
	public T getOrElse(T def) {
		return def;
	}

	@Override
	public boolean hasValue() {
		return false;
	}

}

public static Option<Integer> parseInt(String s) {
	Option<Integer> result = new None<Integer>();
	try {
		Integer value = Integer.parseInt(s);
		result = new Some<Integer>(value);
	} catch (NumberFormatException e) {
	}
	return result;
}
 

}

4voto

Andreas_D Points 64111

Après avoir lu les réponses à la question je pense que l'encapsulation ou de l'emballage de la méthode parseInt n'est pas nécessaire, peut-être même pas une bonne idée.

Vous pouviez retourner 'null', comme Jon l'a suggéré, mais c'est plus ou moins le remplacement d'un try/catch par un null-case. Il y a une légère différence sur le comportement si vous "oubliez" erreur de manipulation: si vous n'attrapez pas l'exception, il n'y a pas d'affectation et le côté gauche de la variable conserve l'ancienne valeur. Si vous n'avez pas fait de test pour les nuls, vous aurez probablement touché par la JVM (NPE).

bâiller la suggestion de l'air plus élégant pour moi, parce que je n'aime pas retourner null pour signaler des erreurs ou des états. Maintenant, vous devez vérifier référentielle de l'égalité avec un objet prédéfini, qui indique un problème. Mais, comme d'autres l'affirment, nouveau si vous "oubliez" pour vérifier et d'une Chaîne de caractères est unparsable, le programme continue à le enveloppés int à l'intérieur de votre "ERREUR" ou "NULLE" de l'objet.

Nikolay solution est encore plus orienté objet et de travailler avec des parseXXX méthodes des autres classes wrapper aswell. Mais à la fin, il a juste remplacé le NumberFormatException par un OperationNotSupported exception - encore une fois vous avez besoin d'un try/catch pour gérer unparsable entrées.

Donc, ma conclusion pour ne pas encapsuler la plaine parseInt méthode. Je n'avais encapsuler si je pouvais ajouter quelques (application dépendait) erreur de manipulation ainsi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X