11
votes

Comment créer une réplique de classe de cordes?

J'ai besoin de créer une classe avec exactement les mêmes méthodes que java.lang.string .

Quelle est la meilleure façon de le faire en Java?

Je sais que je ne peux pas prolonger la classe de chaîne car il est final . Je ne regarde pas les solutions où j'ai besoin de copier le code source de java.lang.string . Par exemple, supposons que j'ai besoin de la fonctionnalité longueur () dans ma classe personnalisée nommée mystring , qui a une méthode "mylength ()" correspondante.

Quelle est la meilleure façon d'implémenter mylength () ?

Je ne regarde pas divers algorithmes pour trouver la longueur d'une chaîne, mais pour réutiliser string 'S longueur () méthode. Maintenant, une fois que j'ai MyString Classe Prêt, je devrais pouvoir l'utiliser n'importe où pour mes manipulations personnalisées.


9 commentaires

Quel est le problème réel que vous essayez de résoudre?


J'essaie de savoir quel modèle de conception conviendrait le mieux à ce genre de problème.


Je me suis toujours demandé cependant, pourquoi la chaîne est finale à Java? Bien sûr, il fournit toutes les fonctionnalités que j'ai besoin et jamais pensé à une opération qui nécessiterait une extension de la chaîne de classe, mais vous ne saurez toujours jamais ce que quelqu'un pourrait avoir besoin!


@Alex: Le choix pourrait avoir plus à faire avec la sécurité que la conception. Ne me demandez pas de clarifier cela cependant, comme je pense que c'est juste quelque chose que je peux (ou que je ne peux pas) avoir lu ;-)


@ALEX: Le JVM peut optimiser le Bejesus sur les classes de code finales, car elle sait qu'il ne peut jamais y avoir de sous-classe.


La source est dans la JDK pour que vous le copiez, même la modifiez à vos risques et périls.


@ALEX, voir ici: Stackoverflow.com/ Questions / 2068804 / Pourquoi-string-is-final-in-j Ava


@Yishai oui, je sais :) J'ai créé cette question :)


J'ai trouvé plusieurs commentaires / questions sur les classes finales populaires telles que la chaîne. Je cherche parce que j'ai une poignée de cas d'utilisation valide où je devrais 'étendre la chaîne; Comme je ne le suis peut-être pas, je dois utiliser un wrapper délégué. Par exemple, je voulais distinguer une chaîne de format à partir d'une chaîne ordinaire (à l'heure de la compilation) - Besoin de la classe de formatage de la formatage pour envelopper la chaîne. Ce n'est peut-être pas une meilleure solution pour avoir la construction qui utilise la sémantique "envelopper" plutôt que d'étendre une chaîne. Telle que: "chaîne de formatrage wraps" ...?


8 Réponses :


2
votes

Faites une nouvelle classe (il aura besoin d'un package différent, bien sûr, implémentez la même interface et ajoutez toutes les méthodes publiques de la classe de cordes (lire le Javadoc pour vous assurer de tout avoir tout).

Je dois supposer que cela concerne les devoirs.


0 commentaires

8
votes

Etant donné que Final code> Les classes ne peuvent pas être sous-classées, créez une nouvelle classe que a une string forte> code> instance code> à l'intérieur et fonctionnez sur cet objet.

public class MyString {
  private String s;

  public MyString( String s ) {
    setInternalString( s );
  }

  public int myLength() {
    return getInternalString().length();
  }

  private void setInternalString( String s ) {
    this.s = s;
  }

  private String getInternalString() {
    return this.s == null ? "" : this.s;
  }
}


0 commentaires

3
votes

Je suppose que vous voulez dire java.lang.string . Cependant, vous ne pouvez pas remplacer chaîne avec votre propre classe. Vous pouvez créer une autre classe avec les mêmes méthodes (en copiant le code source et en modifiant la déclaration de package), mais vous ne pourrez pas passer des instances de cette classe à des méthodes nécessitant une chaîne . < / p>

qui soulève une question importante: pourquoi pensez-vous que vous voulez faire cela?


3 commentaires

Je ne veux pas créer une classe juste en copiant toutes les méthodes de la classe de cordes. Cette question m'a été posée dans une interview.


Peut-être que c'était une question truc et que vous étiez censé leur expliquer pourquoi cela vous empêcherait d'inter-opérer avec une API Java presque existante.


Une autre réponse à l'entretien serait indiquée que la chaîne implémente la Chaluquant et vous pouvez créer d'autres implémentations. Bien sûr, cela n'aide pas si les API qui utilisent la chaîne Ersatz nécessitent une chaîne plutôt que par un charcuternence.



0
votes

Si vous voulez simplement remplacer une partie du comportement de la chaîne, vous pouvez essayer d'utiliser un proxy dynamique. Rechercher java.lang.reflect.proxy dans l'API.


1 commentaires

Le support de proxy dynamique intégré ne fonctionne que avec des interfaces. Les bibliothèques ASM et autres Bytecode peuvent travailler avec des cours, mais je ne suis pas sûr des classes finales.



3
votes

Proxy modèle de conception, je suppose. C'est une question stupide, cependant (pas une réflexion sur l'astucieux, mais sur la personne qui lui a posé sa question dans un entretien d'embauche). Peut-être que la personne qui vous demande n'a pas réalisé que la chaîne est finale? Sinon, je ne peux pas penser pourquoi ils demanderaient même.


1 commentaires

Je pense que le vrai défi réside dans le fait que la chaîne est définitive. Sinon, la réponse est assez simple. Il suffit d'étendre la chaîne et vous avez terminé.



6
votes

De votre question, il ressemble à la chose que vous recherchez est simple délégation :

class MyString {

  String delegate; // The actual string you delegate to from your class

  public MyString(String delegate) {
    this.delegate = delegate; // Assign the string that backs your class
  }

  int length() {
    return delegate.length(); // Delegate the method call to the string
  }

  // other methods that delegate to the string field
}


6 commentaires

Cela semble bon. Mais puis-je faire mystring STRABC = "Ceci est ma chaîne"? Je cherche une réplique exacte de la chaîne. Dans votre solution, je devrais passer la chaîne dans le constructeur.


@ Harsha, ce que vous voulez, n'est tout simplement pas possible.


@Paul pouvez-vous s'il vous plaît expliquer?


@HARSHA, j'ai ajouté une réponse à expliquer plus complètement que ces commentaires permettent.


@Harsha pas de problèmes ... Si c'est utile, et upvote est toujours sympa ;-)


@Paul: Malheureusement, j'ai atteint mon quota quotidien de upvotes. Je voudrais sûrement le remettre demain.



1
votes

Vous pouvez utiliser le refactoring: Remplacer l'héritage avec la délégation , qui est essentiellement (comme indiqué Dans les réponses précédentes) Pour créer une variable d'instance du type souhaité et implémenter toutes ses méthodes dans la nouvelle classe et leur transmettre le message.

créer un champ pour la superclasse, ajustez les méthodes pour déléguer à la superclasse et supprimer le sous-classement.

https://www.refactoring.com/catalog/repinherwithdel.gif

Vous remarquerez que c'est beaucoup de dactylographier, c'est quand un bon IDE vient utile.

La vidéo suivante montre comment l'idée de Intellij l'a fait.


0 commentaires

12
votes

passer par les différentes réponses ici, ainsi que les mises à jour et clarifications d'Askers, il apparaît que ce que l'Asker veut est une classe qui ressemble, sent et sonne comme une chaîne, mais n'est pas.

C'est-ce qu'ils aimeraient être capable de faire: xxx

Ceci ne peut pas fonctionner, car java.lang.string est une classe finale, et donc chaque " " que le compilateur produit sera un objet java.lang.string , car ce n'est pas un objet mystring , ils ne peuvent pas être attribués à l'autre.

Dans des langues faiblement typées, vous seriez en mesure de créer une telle classe, car si une classe a l'air, sent et sonne comme un Duck , puis à toutes fins utiles, c'est un canard. Java, cependant, est une langue fortement dactylographiée, et un canard n'est qu'un canard si elle se trouve à partir du Anatidae Famille d'oiseaux .


1 commentaires

+1 c'est vrai. Donc, l'utilisateur a demandé une réplique à chaîne et non un délégué, où un délégué créera toujours un objet à chaîne.