2010-08-02 22 views
7

Possible en double:
Why is String final in Java?Pourquoi la classe String est-elle finale?

Il y a plusieurs moments dans ma vie de programmation que je voulais la classe String n'a pas été finale/scellé/NotInheritable. Qu'est-ce que les architectes de la langue qui essaient de m'empêcher de faire qui jetteraient une clé de singe dans les travaux. Au lieu de cela, quelles sont les clefs de singe que les architectes de langage voudraient m'empêcher de jeter dans les travaux en me limitant d'étendre la classe de corde?

Pourriez-vous dresser une liste des avantages de la classe de chaînes extensible?

+0

Je me rends compte qu'il existe d'autres classes comme les numériques qui sont également scellés. Nous pourrions commencer par analyser la chaîne d'abord mais vos commentaires ne doivent pas être limités à la chaîne. –

+0

+1 ... Je voulais aussi une fois dans ma vie étendre la classe String, même si je ne me souviens pas pourquoi –

+0

Comme vous l'avez mentionné java (tag), cela a déjà été demandé: http://stackoverflow.com/questions/2068804/pourquoi-est-string-final-en-java –

Répondre

5

La chaîne est un immutable class ce qui signifie que vous ne pouvez pas modifier son état après l'avoir créé. Si vous pouviez modifier une chaîne après l'avoir entrée dans une autre bibliothèque, ou une carte par exemple, le résultat serait imprévisible. Une erreur de l'API Java est que BigInteger et BigDecimal ne sont pas définitifs, ce qui signifie que vous devez effectuer une copie défensive de ces objets lors de la réception d'un code non sécurisé. Inversement, vous pouvez toujours avoir confiance qu'un String restera cohérent.

ADORE BigInteger:

public class DestructiveBigInteger extends BigInteger { 

    public DestructiveBigInteger(String value) { 
     super(value); 
    } 

    public BigInteger add(BigInteger val) { 
     return BigInteger.ONE; // add() method does not behave correctly 
    } 

    public BigInteger subtract(BigInteger val) { 
     throw new UnsupportedOperationException("subtract is broken"); 
    } 
} 

La même chose est impossible avec String. Comme indiqué dans Effective Java, vous avez besoin de faire des copies de défense de ces types d'objets:

public void setValue(BigInteger value) { 
    this.value = new BigInteger(value.toByteArray()); 
} 
+0

Elaborer, pls. –

+1

Assurez-vous de connaître la différence entre le mot-clé * final * et le mot-clé * sealed *. Les classes marquées * final * sont AUSSI * effectivement scellées *, mais ce n'est pas le point réel du mot-clé * final *. Une classe * final * est ** immuable **, ce qui signifie qu'elle ne peut pas être modifiée après sa création. Les classes immuables doivent également être scellées, sinon on pourrait hériter, surcharger et ajouter un comportement non immuable. Les chaînes sont immuables dans Java parce que les chaînes mutables sont ** dangereuses **, et, franchement, plus de problèmes qu'elles n'en valent. La plupart des langages modernes (Python, Javascript, C#, Java), utilisent des chaînes immuables. – Ender

4

chaîne est définitive, car elle représente un type de données immuables. La multiplicité des variétés résulterait de l'extension naïve de la chaîne, car il y a beaucoup de bibliothèques qui dépendent de l'immuabilité des objets String. Extension de chaîne pour le rendre mutable serait invisible à tout code que le Sting traverse, mais aurait des effets secondaires très surprenants et méchants comme soudainement ne pas être en mesure de charger des valeurs de HashMaps même si vous avez littéralement la chaîne de la clé car le hashCode aurait été piraté.

+0

Si je voulais utiliser la chaîne pour les clés d'une carte, j'utiliserais String. Si je voulais utiliser une chaîne étendue comme clé d'une carte, c'est exactement ce que je veux faire - pour l'empêcher d'être accessible avec des objets String de base. L'argument de l'immutabilité ne semble pas retenir l'eau pour moi. –

+0

Mais une chaîne étendue * serait * une chaîne. Vous pouvez donc l'utiliser comme clé d'une carte de String. Ne pas pouvoir dériver ne vous empêche pas d'écrire une classe qui étend les capacités de String (en utilisant la composition). Cela vous empêche de créer des instances de cette classe dans Strings. – jwg