Request for Enhancement: java.io.Writer.of(Appendable) as an efficient alternative to java.io.StringWriter

Markus KARG markus at headcrashing.eu
Sun Apr 6 09:22:43 UTC 2025


Chen,

thank you for your API documentation proposal.

For me it is easier to have some code at hand to discuss about, so I 
have filed a Jira-Ticket https://bugs.openjdk.org/browse/JDK-8353795 
with accompanying PR https://github.com/openjdk/jdk/pull/24469, and I 
would propose to continue our discussion in that PR's thread. I will 
adapt the PR to stay aligned with the discussion.

Regards
-Markus

Am 24.03.2025 um 04:48 schrieb Chen Liang:
> Indeed, you are right: The Writer is for legacy APIs to consume 
> instead of intended for users to operate on directly. The lack of IOE 
> on those methods have no impact on the users. Even if we bikeshed 
> about try-catching the returned Writer, StringWriter still declares to 
> throw IOE on its close method, so returning it as a concrete type 
> provides little value.
>
> That said, we can probably start drafting the API documentation of 
> this new API Writer.of(StringBuilder):
>
> {@return a character stream that redirects to a specified StringBuilder}
> <p>
> The {@code write} and {@code append} invocations are redirected to the 
> {@code append} methods with the same parameter types on the specified 
> StringBuilder, except {@code write(int)}, which delegates to {@code 
> append(char)}. The {@code flush} and {@code close} invocations have no 
> effect.
>
> I propose to specify this explicitly as a delegation proxy; we can 
> infer the lack of thread safety from StringBuilder. (If we want, we 
> can add an API note asking to use StringWriter if thread safety is 
> needed). Also, we don't specify the toString behavior on the returned 
> Writer (unlike for StringWriter); I think users should just use the 
> toString on the StringBuilder.
>
> Chen
>
> ------------------------------------------------------------------------
> *From:* core-libs-dev <core-libs-dev-retn at openjdk.org> on behalf of 
> Markus KARG <markus at headcrashing.eu>
> *Sent:* Sunday, March 23, 2025 11:02 AM
> *To:* Chen Liang <liangchenblue at gmail.com>
> *Cc:* core-libs-dev <core-libs-dev at openjdk.org>
> *Subject:* Re: Request for Enhancement: java.io.Writer.of(Appendable) 
> as an efficient alternative to java.io.StringWriter
>
> Chen,
>
> limiting param type to StringBuilder (instead of Appendable) really 
> makes things easier (without standing in the way of some future more 
> general of() variant, eventually): We can easily clarify in JavaDocs 
> how things work like (in the sense of "close and flush are no-ops"). I 
> will prepare a PR on that agreement to have some code at hand to 
> discuss in detail.
>
> Restricting result type to StringWriter (instead of Writer) IMHO is 
> *impossible*, due to the existence of StringWriter::getBuffer(): That 
> method returns StringBuffer, which is synchronized (hence spoils the 
> core idea of Writer.of(): being *non*-synchronized), and unfortunately 
> also is final (so we can't get rid of synchronized using inheritance). 
> Did I miss something?
>
> Anyways, I actually think that being *as least specific as possible* 
> regarding the actual result type is a *good* thing, so users do not 
> imply anything, but actually accept the rules we lay out in the 
> JavaDocs. We should not limit our future possibilities to change 
> without good reason.
>
> -Markus
>
>
> Am 23.03.2025 um 10:06 schrieb Chen Liang:
>> Sorry for a late reply.
>> I wonder if we should make the return type 
>> StringWriter, given StringWriter does not throw on its Writer methods 
>> and has a convenient toString. (Making its close() not throws IOE is 
>> binary compatible but possibly not source compatible)
>> I think this StringBuilder-accepting version in general fits most of 
>> the demands, and we can make it emulate StringWriter in a lot of 
>> behaviors and avoid the nasty issues around closing/flushing.
>>
>> On Sat, Mar 15, 2025, 12:58 PM Markus KARG <markus at headcrashing.eu 
>> <mailto:markus at headcrashing.eu>> wrote:
>>
>>     Chen,
>>
>>     thank you for sharing your opinion!
>>
>>     Thinking about what you wrote about the "trifecta" complexity, I
>>     think
>>     it might be better to restart my idea from scratch:
>>
>>     As explained in my original proposal
>>     (https://mail.openjdk.org/pipermail/core-libs-dev/2024-December/137807.html
>>     <https://mail.openjdk.org/pipermail/core-libs-dev/2024-December/137807.html>),
>>
>>     the actual driver for my proposal was to provide a StringWriter
>>     alternative which solves two main problems: It shall prevent String
>>     copies, and it shall be non-synchronized.
>>
>>     What comes into mind is: Writer.of(StringBuilder).
>>
>>     While compared to Appendable this signature is much less
>>     flexible, it
>>     also makes less headaches, but solved in fact those 99% of cases
>>     that
>>     triggered this whole idea: It does not create String copies, and
>>     it is
>>     non-synchronized. What this writer would simply, simply would be
>>     routing
>>     all incoming "append" and "write" calls down to the provided
>>     string builder.
>>
>>     Hence, kindly asking for comments on this updated idea: WDYT about
>>     Writer.of(StringBuilder)?
>>
>>     Thanks!
>>
>>     -Markus
>>
>>
>>     Am 10.02.2025 um 01:51 schrieb Chen Liang:
>>     > Hi Mark,
>>     > After thinking about the Appendable-Closeable-Flushable trio
>>     versus
>>     > Writer, I believe that one problem with Writer.of is that it goes
>>     > against interface segregation principle represented by the
>>     trifecta,
>>     > and accidentally leaking the Closeable or Flushable
>>     functionality is
>>     > still dubious to me. This appears simple, but it may cause
>>     unintended
>>     > consequences, such as if Appendable b implements Closeable too,
>>     its
>>     > closing behavior is not proxied and users may find this
>>     inconsistency
>>     > weird. And as for interface segregation principle, it means APIs
>>     > should request Appendable instead of Writer if they only need
>>     writing
>>     > abilities with no lifecycle; using Writer as the type implies
>>     > potential dependency on closing/flushing behavior, which can
>>     sometimes
>>     > be dangerous.
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250406/47d2335a/attachment-0001.htm>


More information about the core-libs-dev mailing list