En résumé
L'une est une interface ( CharSequence
) tandis que l'autre est une implémentation concrète de cette interface ( String
).
CharSequence animal = "cat" // `String` object presented as the interface `CharSequence`.
Tout comme ArrayList
est un List
et HashMap
est un Map
donc aussi String
est un CharSequence
.
En tant qu'interface, normalement le CharSequence
serait plus fréquente que String
mais une histoire tordue a fait que l'interface a été définie il y a des années. après la mise en œuvre. Ainsi, dans les anciennes API, on voit souvent String
alors que dans les API plus récentes, nous avons tendance à voir CharSequence
utilisé pour définir les arguments et les types de retour.
Détails
Aujourd'hui, nous savons qu'en général, une API/un cadre de travail doit se concentrer sur l'exportation d'interfaces en premier lieu et de classes concrètes en second lieu. Mais cette leçon n'a pas toujours été aussi bien connue.
En String
est arrivé premier en Java. Ce n'est que plus tard qu'ils ont placé une interface frontale, CharSequence
.
Une histoire tordue
Un peu d'histoire pourrait aider à la compréhension.
À ses débuts, Java a été commercialisé un peu avant l'heure, en raison de la manie de l'Internet et du Web qui animait l'industrie. Certaines bibliothèques n'étaient pas aussi bien pensées qu'elles auraient dû l'être. La gestion des chaînes de caractères était l'un de ces domaines.
De plus, Java a été l'une des premières applications non universitaires orientées vers la production. Programmation orientée objet (POO) environnements. Les seules implémentations réussies de la POO dans le monde réel avant cela étaient quelques versions limitées de SmallTalk alors Objectif-C con NeXTSTEP / OpenStep . De nombreux enseignements pratiques restaient donc à tirer.
Java a commencé avec le String
et StringBuffer
classe. Mais ces deux classes n'étaient pas liées, ni par héritage ni par interface. Plus tard, l'équipe Java a reconnu qu'il aurait dû y avoir un lien unificateur entre les implémentations liées aux chaînes de caractères pour les rendre interchangeables. Dans Java 4, l'équipe a ajouté la classe CharSequence
et implémenté rétroactivement cette interface sur String et String Buffer, ainsi qu'ajouté une autre implémentation CharBuffer
. Plus tard, dans Java 5, ils ont ajouté StringBuilder
qui est essentiellement une version non synchronisée et donc un peu plus rapide de StringBuffer
.
Ces classes orientées cordes sont donc un peu confuses et difficiles à appréhender. De nombreuses bibliothèques et interfaces ont été construites pour prendre et retourner String
objets. De nos jours, de telles bibliothèques doivent généralement être construites pour s'attendre à ce que CharSequence
. Mais (a) String
semble toujours dominer l'espace mental, et (b) il peut y avoir des problèmes techniques subtils lorsque l'on mélange les différents types de produits. CharSequence
mises en œuvre. Avec la vision 20/20 du recul, nous pouvons voir que toute cette histoire de chaîne aurait pu être mieux gérée, mais nous y sommes.
Idéalement, Java aurait commencé par une interface et/ou une superclasse qui serait utilisée dans de nombreux endroits où nous utilisons aujourd'hui String
tout comme nous utilisons le Collection
o List
à la place de l'interface ArrayList
o LinkedList
mises en œuvre.
Interface versus classe
La principale différence entre CharSequence
est qu'il s'agit d'un interface et non un mise en œuvre . Cela signifie que vous ne pouvez pas instancier directement un CharSequence
. Vous instanciez plutôt l'une des classes qui implémente cette interface.
Par exemple, ici nous avons x
qui ressemble à un CharSequence
mais en dessous, il y a en fait un StringBuilder
objet.
CharSequence x = new StringBuilder( "dog" ); // Looks like a `CharSequence` but is actually a `StringBuilder` instance.
Cela devient moins évident lorsqu'on utilise une chaîne littérale. Gardez à l'esprit que lorsque vous voyez du code source avec seulement des guillemets autour des caractères, le compilateur le traduit en un objet String.
CharSequence y = "cat"; // Looks like a `CharSequence` but is actually a `String` instance.
Littéral contre constructeur
Il y a quelques différences subtiles entre "cat"
y new String("cat")
tel que discuté dans cette autre question mais ne sont pas pertinents ici.
Diagramme de classe
Ce diagramme de classe peut vous aider à vous orienter. J'ai noté la version de Java dans laquelle ils sont apparus pour montrer à quel point ces classes et interfaces ont évolué.
Blocs de texte
À part ajouter plus Unicode personnages, dont une multitude de emoji Ces dernières années, peu de choses ont changé en Java pour le travail avec du texte. Jusqu'à ce que blocs de texte .
Les blocs de texte sont une nouvelle façon de mieux gérer les chaînes de caractères de plusieurs lignes ou de plusieurs pages. Mise en forme des caractères . Cela rendrait l'écriture de chaînes de code intégrées telles que HTML, XML, SQL ou JSON beaucoup plus pratique.
Je cite JEP 378 :
Un bloc de texte est une chaîne de caractères littérale de plusieurs lignes qui évite la plupart des séquences d'échappement, formate automatiquement la chaîne de manière prévisible et permet au développeur de contrôler le format lorsqu'il le souhaite.
La fonction de blocs de texte fait no introduire un nouveau type de données . Les blocs de texte sont simplement une nouvelle syntaxe pour l'écriture d'une String
littérale. Un bloc de texte produit un String
tout comme la syntaxe littérale conventionnelle. Un bloc de texte produit un String
qui est aussi un objet CharSequence
comme indiqué ci-dessus.
Exemple SQL
Pour citer à nouveau JSR 378
Utilisation de littéraux de chaîne "unidimensionnels".
String query = "SELECT \"EMP_ID\", \"LAST_NAME\" FROM \"EMPLOYEE_TB\"\n" +
"WHERE \"CITY\" = 'INDIANAPOLIS'\n" +
"ORDER BY \"EMP_ID\", \"LAST_NAME\";\n";
Utilisation d'un bloc de texte "bidimensionnel".
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
Les blocs de texte se trouvent dans Java 15 et plus tard, par JEP 378 : Blocs de texte .
Présenté en avant-première dans Java 13, sous JEP 355 : Blocs de texte (aperçu) . Puis prévisualisé à nouveau dans Java 14 sous JEP 368 : Blocs de texte (deuxième aperçu) .
Cet effort a été précédé par JEP 326 : Littératures de chaînes brutes (Preview) . Les concepts ont été retravaillés pour produire le Blocs de texte à la place.
12 votes
Cela va vous paraître très "RTFM", mais c'est un conseil honnête : il peut être très intéressant et instructif de regarder le code source de String par vous-même.
1 votes
Où pouvez-vous trouver le code source Java ? Je croyais qu'il était propriétaire ?
4 votes
@aaronsnoswell : OpenJDK est open source. Vous pouvez trouver une version du
String
classe à hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/6069fe8ffead/src/share/ . Mais même avant cela, les JDKs Sun étaient livrés avec un fichier appelésrc.zip
qui contenait une grande partie du code source. Il était possible et utile de consulter ce code, mais le modifier était probablement une autre affaire, en termes de licence.0 votes
En ce qui concerne le code source, de nombreuses entreprises donnent accès, par le biais de leurs propres sites web, à divers projets open source, dont OpenJDK. Simplement utiliser un moteur de recherche pour une requête telle que "java string class source code" pour obtenir plusieurs résultats sur ces fournisseurs.
0 votes
Similaire à : Pourquoi StringBuilder quand il y a String ?
0 votes
Oh mon dieu, est-ce que Oracle ne publie plus les sources avec leur JDK ?