Quel est le Throwable préféré à utiliser dans un constructeur de classe utilitaire privé?

StackOverflow https://stackoverflow.com/questions/398953

  •  29-08-2019
  •  | 
  •  

Question

Effective Java (deuxième édition) , point 4, les constructeurs privés traite de l'utilisation à appliquer noninstantiability. Voici l'exemple de code du livre:

public final class UtilityClass {
    private UtilityClass() {
        throw new AssertionError();
    }
}

Cependant, AssertionError ne semble pas la bonne chose à jeter. Rien n'est « affirmé », qui est la façon dont l'API définit l'utilisation de AssertionError .

Y at-il un autre Throwable qui est généralement dans cette situation? Doit-on habituellement juste jeter un Exception général avec un message? Ou est-il d'écrire un commun Exception personnalisé pour cela?

Il est assez trivial, mais plus que tout ce que je suppose que je suis juste curieux à ce sujet d'un style et des normes perspective.

Était-ce utile?

La solution

Il y a une affirmation: «J'affirme que ce constructeur ne sera jamais appelé ». Alors, en effet, AssertionError est correct ici.

Autres conseils

J'aime y compris le commentaire de Bloch:

// Suppress default constructor for noninstantiability

Ou mieux encore mettre dans l'erreur:

private UtilityClass()
{
    throw new AssertionError("Suppress default constructor for noninstantiability");
}

UnsupportedOperationException sonne comme le meilleur forme, mais une exception vérifiée serait encore mieux, car il pourrait avertir quelqu'un instanciation par erreur la classe au moment de la compilation.

Qu'en est- IllegalAcessError ? :)

Non non non, avec tout le respect dû à Josh Bloch, Ne jamais jeter un AssertionError à moins qu'elle soit d'une affirmation. Si vous voulez un AssertionError ici, jetez-le avec assert(false). Ensuite, une personne lisant le code peut trouver plus tard.

Mieux encore, définir votre propre exception, par exemple CantInstantiateUtilityClass. alors vous aurez un code qui dit

try {
    // some stuff
} catch (CantInstantiateUtilityClass e) {
    // react
}

pour que le lecteur du receveur sait ce est arrivé.

Mise à jour

Chaque si souvent une imbécile vagabonde par ici et downvotes cette fois, près de quatre ans après le fait. Alors, laissez-moi juste noter que la norme toujours définit AssertionError à la suite d'une assertion a échoué, pas ce que certains débutants pense devriez- pour être jeté en place d'un bien définie exception informative. Malheureusement, une bonne discipline d'exception est peut-être le moins compétence dans la programmation Java encouragée.

Lorsque le code requiert l'inclusion du JUnit comme une dépendance, comme dans le cadre test maven <scope>test</scope>, puis aller directement à Assertion.fail() méthode et de bénéficier d'une amélioration significative de la clarté.

public final class UtilityClass {
    private UtilityClass() {
        fail("The UtilityClass methods should be accessed statically");
    }
}

Quand en dehors du champ de test, vous pouvez utiliser quelque chose comme ce qui suit, ce qui nécessiterait une importation statique à utiliser comme ci-dessus. import static pkg.Error.fail;

public class Error {
    private static final Logger LOG = LoggerFactory.getLogger(Error.class);
    public static void fail(final String message) {
        LOG.error(message);
        throw new AssertionError(message);
        // or use your preferred exception 
        // e.g InstantiationException
    }
}

Ce qui suit l'utilisation.

public class UtilityClassTwo {
    private UtilityClassTwo() {
        Error.fail("The UtilityClass methods should be accessed statically");
    }
}

Dans sa forme la plus idiomatiques, ils ont tous faire bouillir à ceci:

public class UtilityClassThree {
    private UtilityClassThree() {
        assert false : "The UtilityClass methods should be accessed statically";
    }
}

L'une des exceptions construit, UnsupportedOperationException peut être jeté à indique que «l'opération demandée est pas pris en charge.

 private Constructor() {
    throw new UnsupportedOperationException(
            "Do not instantiate this class, use statically.");
}

Une assertion brisée signifie que vous avez cassé une spécification de contrat de votre code. Il est donc la bonne chose ici.

Cependant, comme je suppose que vous serez privé instancier une instance, il appellera également le constructeur et provoquer une ERROR- sauf si vous avez un autre constructeur?

Vous pouvez créer votre propre classe extension Throwable, par exemple:.

class NoninstantiabilityError extends Throwable

présente les avantages suivants:

  • Le nom indique le problème
  • Parce qu'il étend directement Throwable il est peu probable qu'il sera pris par hasard
  • Parce qu'il étend directement Throwable il est vérifié et appeler le constructeur concerné par accident, il faudrait attraper l'exception

Exemple d'utilisation:

public final class UtilityClass {
    private UtilityClass() throws NoninstantiabilityError {
        throw new NoninstantiabilityError();
    }

    ...
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top