Привет. Можно понять, почему StringReader и BufferedReader при попытке вывести их в консоль, выводят своё место в памяти. Происходит это, так как мы передали им в конструктор строку или файл: StringReader(в его конструкторе уже есть наша строка), InputStreamReader или FileReader и т.п. То есть, их либо нужно сначала прочитать, либо строка у нас уже есть. Напротив, при записи во StringWriter, вывести нормальную строку мы можем, что логично. Мы что-то долго записывали(возможно через цикл) или сериализовывали и теперь можем удобно вывести. Тогда у меня возникает вопрос: почему в декораторе этого StringWriter(который, по сути, должен быть круче), а именно класса BufferedWriter, мы имеем toString(возможно из Object), выводящий адрес памяти этого конкретного обьекта, как и вышеупомянутые имплементации Reader? Только там оправданно, а тут неясно и неудобно. С чем это может быть связано?
hidden #1281202
41 уровень
Почему BufferedWriter.toString() не имеет ничего общего со StringWriter.toString()?
Решен
Комментарии (3)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
JustinianJudge в Mega City OneMaster
27 июля 2019, 20:12решение
Интересный вопрос,мои мысли вслух.
BufferedWriter это декоратор абстрактного класса Writer.
StringWriter лишь один из многих типов объектов, которые могут быть переданы в конструктор BufferedWriter.
Кроме того, StringWriter, как и например CharArrayWriter который также имеет переопределенный метод toString() являются достаточно специфическими инструментами в контексте иерархии Writer, ведь по сути (что видно по их реализации) они являют собой стринг или чар буффер, который МОЖЕТ использоваться как Writer там где удобно использование именно Writer API.
Поэтому логику наличия toString у StringWriter, CharArrayBuffer если говорить про символьные потоки, или ByteArrayOutputStream если говорить про байтовые, уловить можно.
В описаниях этих классов, акцентировано внимание на том, что это стримы, которые собирают данные в те или иные структуры данных, и которые можно получить при помощи разных методов, включая toString().
Окей. Есть смысл, эти классы представляют собой буфер, в котором собираются данные.
Но в описании BufferedWriter указано другое, это инструмент записи в символьный исходящий стрим при помощи промежуточного буфера для оптимизации "тяжелых" операций.
Соответственно, в чем смысл возможности вывести на экран содержимое буфера, которое ни программист ни пользователь предсказать не может что выведется. В отличие от трех упомянутых классов выше.
Это undefined behavior которое должно избегаться.
Послали в буфер кусок текст, допустим главу Войны и мир, отправляем там частями.
И тут вызываем System.out.println(bufferedWriter);
получаем на экран
Какую ценность это нам даст? Остача информации в буфере..
Тут вопрос шире, что такое символьный поток, чем он отличается от потока чаров и почему на уровне Writer в принципе не переопределили toString(), раз речь о символьном потоке.
А BufferedWriter частный пример инструмента, задача которого писать. СтрингРайтер относится к другой плоскости.
+4
hidden #1281202
28 июля 2019, 10:23решение
Решил, что лучше всего взглянуть на это через призму наглядного примера:
Output:
Который, собственно, и расставляет все акценты у вопросах, что и как должно работать. А именно: StringWriter записывает в себя символьные потоки(за счёт внутреннего расширяющегося буфера) и представляет собой строку, к которой всегда можно что-то добавить; BufferedWriter же выступает инструментом, оптимизирующим данное действие с помощью временных накоплений в своём буфере из источника(то есть, сокращает число обращений к файлу/ресурсу в памяти) Таким образом, нету смысла ловить что-либо из грузовика доставщика, думая, что там может быть товар, который тебе нужен - нужно узнать на складе, куда этот грузовик доставляет весь товар(иногда, правда, частями)
Временами новый день и взгляд со стороны дают возможность посмотреть на проблему из другой "плоскости", спасибо за комментарий)
+3
hidden #1281202
28 июля 2019, 10:50
А отсутствие своего toString в классе Writer, возможно, обусловлено наличием подобных инструментов-предков. Им(инструментам) нужен стандартный toString класса Object, а если переопределять toString, который выводит текст, во Writer, что бы потом как минимум в BufferedWriter(а на самом деле, никто не знает, сколько ещё таких инструментов будет) переопределять свои toString, в которых надо будет дублировать поведение из toString Object. Невкусно, правда?
+1