<div dir="ltr">Hi,<br><br>First as to your problem statement - if a method could be implemented with a default method on CharSequence then there is nothing stopping library owners from either<br><br>1. Extending the CharSequence interface<br><br><font face="monospace"> interface RichCharSequence extends CharSequence {<br> default byte[] getBytes() {<br> byte[] bytes = new byte[this.length()];<br> // ...<br> return bytes;<br> }<br><br> static RichCharSequence from(CharSequence csq) {<br> // ...<br> }<br> }</font><br><br> (see <a href="https://javadoc.io/doc/io.vavr/vavr/0.9.0/io/vavr/collection/CharSeq.html">https://javadoc.io/doc/io.vavr/vavr/0.9.0/io/vavr/collection/CharSeq.html</a>)<br><br>2. Using static methods defined in their projects or in dependencies <br><br><font face="monospace"> class CharSequenceUtils {</font><br><font face="monospace"> private CharSequenceUtils() {</font><br><font face="monospace"> }</font><br><br><font face="monospace"> public static byte[] getBytes(CharSequence csq) {</font><br><font face="monospace"> // ...</font><br><font face="monospace"> }</font><br><font face="monospace"> }</font><br><br><font face="arial, sans-serif">So your problem comes down to the fact that there are libraries out there which take </font><font face="monospace">String</font><font face="arial, sans-serif">s as arguments that you wish took </font><font face="monospace">CharSequence</font><font face="arial, sans-serif">s. That problem is not mechanical, it is social. Your proposed solutions are ways to "force" those library owners to support your use case by making it so </font><font face="monospace">String</font><font face="arial, sans-serif"> means something different than it does or to add more functionality to </font><font face="monospace">CharSequence</font><font face="arial, sans-serif"> such that it might be more socially convenient to make the change.<br><br>> </font>One solution could be to add many of strings useful methods to CharSequence and implement them with default methods based on the existing abstract methods (or throw exception). These defaults could than be overridden by implementers that have more context to provide a more efficient implementation. <br><br>I think it's reasonable to propose methods that you feel <font face="monospace">CharSequence</font> is "missing," but "make it equal to String" is not. CharSequence does represent a slightly different concept and methods like <font face="monospace">toLowerCase </font><font face="arial, sans-serif">might not make that much sense.<br><br>> </font>Another approach could be to add a new interface that mirrors strings methods and is implemented by string decoupling the method api of string from the fixed string class.<br><br>Say there was a <font face="monospace">StringLike</font><font face="arial, sans-serif"> interface. I'm not convinced it solves your problem. Say the contract of that interface said "must be an immutable character sequence, randomly indexable, yada yada". To be actually interchangeable with String then you would have to be sure that every expression involving a string would work the same or in a similar way<br><br> // How is String going to account for a StringLike argument to equals?<br> // Tricky conceptually, but also likely a performance regression<br> "abc".equals(stringLike)<br><br>> </font>An even more radical and most likely most difficult/breaking approach would be to make string itself an interface. This solution would have the upside that all existing libraries would suddenly accept the interface instead of the locked down class without migrating each library seperatly. <br><br>It is far too late to do this. The bytecode for invoking an interface method is different than for invoking a class method. There is no way, absent significant and costly VM heroics, to make that a binary compatible change. All existing JVM code in the world would break.<br><br>We also cannot make <font face="monospace">String</font> non-final. Various parts of the JVM (and user code) rely on <font face="monospace">String</font>s being truly immutable. A <font face="monospace">String</font> subclass would wreak havoc on everyone's invariants.<br><br>> They all achieve the same goal of allowing libraries to ask for something string like without specifying the explicit implementation (similar to the collections framework) this would allow seamless use of other implementations in libraries without them having to reimplement or work around existing methods from the string class.<div><br>The benefits of achieving this goal (by using the levers available only to the JDK) seem way out of line with the costs.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jun 2, 2023 at 10:14 AM Red IO <<a href="mailto:redio.development@gmail.com">redio.development@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="auto">Since String is a locked down Class part of the standard library it cannot be modified nor subclassed(final).<div dir="auto">Also string directly has a lot of useful methods on hand that the more general CharSequence does not. </div><div dir="auto">This and the fact that CharSequence was only added in later versions (compared to string) causes many libraries to use the type string as arguments.</div><div dir="auto">This makes working with different implementations of text awkward and inefficient (since you often have to convert to string)</div><div dir="auto">There are multiple possible approaches to resolve this issue. </div><div dir="auto"><br></div><div dir="auto">One solution could be to add many of strings useful methods to CharSequence and implement them with default methods based on the existing abstract methods (or throw exception). These defaults could than be overridden by implementers that have more context to provide a more efficient implementation. </div><div dir="auto"><br></div><div dir="auto">Another approach could be to add a new interface that mirrors strings methods and is implemented by string decoupling the method api of string from the fixed string class.</div><div dir="auto"><br></div><div dir="auto">An even more radical and most likely most difficult/breaking approach would be to make string itself an interface. This solution would have the upside that all existing libraries would suddenly accept the interface instead of the locked down class without migrating each library seperatly. The downsides would be that previous to this change all constructors would need to be made private and some code that either used the constructors or was dependant on the class file structure of string might break. Also string literals would need to be rerouted to create an instance of the then internal implementation of string instead. </div><div dir="auto"><br></div><div dir="auto">There sure are other possibilities but those 3 where those I came up with.</div><div dir="auto"><br></div><div dir="auto">They all achieve the same goal of allowing libraries to ask for something string like without specifying the explicit implementation (similar to the collections framework) this would allow seamless use of other implementations in libraries without them having to reimplement or work around existing methods from the string class.</div><div dir="auto"><br></div><div dir="auto">Great regards </div><div dir="auto">RedIODev </div></div>
</blockquote></div>