<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>TIL on monkshark.dev</title><link>https://monkshark.github.io/tags/til/</link><description>Recent content in TIL on monkshark.dev</description><generator>Hugo -- gohugo.io</generator><language>ko</language><lastBuildDate>Sat, 02 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://monkshark.github.io/tags/til/index.xml" rel="self" type="application/rss+xml"/><item><title>Java의 var는 dynamic typing이 아니다</title><link>https://monkshark.github.io/p/java-var-is-type-inference/</link><pubDate>Sat, 02 May 2026 00:00:00 +0000</pubDate><guid>https://monkshark.github.io/p/java-var-is-type-inference/</guid><description>&lt;p&gt;Java 10에서 추가된 지역 변수 &lt;code&gt;var&lt;/code&gt;. 처음 본 사람이 자주 오해하는 부분이 있다.&lt;/p&gt;
&lt;h2 id="var는-컴파일-타임-타입-추론이다"&gt;&lt;a href="#var%eb%8a%94-%ec%bb%b4%ed%8c%8c%ec%9d%bc-%ed%83%80%ec%9e%84-%ed%83%80%ec%9e%85-%ec%b6%94%eb%a1%a0%ec%9d%b4%eb%8b%a4" class="header-anchor"&gt;&lt;/a&gt;var는 컴파일 타임 타입 추론이다
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;hello&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 컴파일 에러&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;var count = 10&lt;/code&gt;을 보면 컴파일러가 우변(&lt;code&gt;10&lt;/code&gt;)을 분석해서 &lt;code&gt;count&lt;/code&gt;의 타입을 &lt;code&gt;int&lt;/code&gt;로 고정한다. 그 뒤로 다른 타입을 대입할 수 없다.&lt;/p&gt;
&lt;p&gt;JavaScript의 &lt;code&gt;var&lt;/code&gt;나 Python 변수와는 다르다. 저쪽은 런타임에 타입이 자유롭게 바뀌지만, Java의 &lt;code&gt;var&lt;/code&gt;는 작성 시점에 이미 타입이 결정되어 있고 단지 직접 적지 않을 뿐이다.&lt;/p&gt;
&lt;h2 id="어디서-쓰면-좋은가"&gt;&lt;a href="#%ec%96%b4%eb%94%94%ec%84%9c-%ec%93%b0%eb%a9%b4-%ec%a2%8b%ec%9d%80%ea%b0%80" class="header-anchor"&gt;&lt;/a&gt;어디서 쓰면 좋은가
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserSummary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 우변에 타입이 보임&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// String임이 명확&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entrySet&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 길어지는 제네릭 생략&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;우변만으로 타입을 즉시 알 수 있을 때는 &lt;code&gt;var&lt;/code&gt;가 가독성을 높여준다.&lt;/p&gt;
&lt;h2 id="어디서-쓰지-않는-게-나은가"&gt;&lt;a href="#%ec%96%b4%eb%94%94%ec%84%9c-%ec%93%b0%ec%a7%80-%ec%95%8a%eb%8a%94-%ea%b2%8c-%eb%82%98%ec%9d%80%ea%b0%80" class="header-anchor"&gt;&lt;/a&gt;어디서 쓰지 않는 게 나은가
&lt;/h2&gt;&lt;h3 id="우변만-봐서는-타입이-안-보일-때"&gt;&lt;a href="#%ec%9a%b0%eb%b3%80%eb%a7%8c-%eb%b4%90%ec%84%9c%eb%8a%94-%ed%83%80%ec%9e%85%ec%9d%b4-%ec%95%88-%eb%b3%b4%ec%9d%bc-%eb%95%8c" class="header-anchor"&gt;&lt;/a&gt;우변만 봐서는 타입이 안 보일 때
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 결과 타입이 뭔지 알기 어려움&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;코드 리뷰어는 IDE 없이 GitHub diff로 보는 경우도 많다. 명시적으로 적어주면 리뷰가 빨라진다.&lt;/p&gt;
&lt;h3 id="람다-매개변수"&gt;&lt;a href="#%eb%9e%8c%eb%8b%a4-%eb%a7%a4%ea%b0%9c%eb%b3%80%ec%88%98" class="header-anchor"&gt;&lt;/a&gt;람다 매개변수
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 컴파일 에러&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;var&lt;/code&gt;는 람다 자체에는 쓸 수 없다. 우변이 람다일 때 좌변 타입을 알아야 컴파일러가 람다를 어떤 함수형 인터페이스로 해석할지 결정할 수 있기 때문이다.&lt;/p&gt;
&lt;h3 id="primitive와-박싱이-의도된-경우"&gt;&lt;a href="#primitive%ec%99%80-%eb%b0%95%ec%8b%b1%ec%9d%b4-%ec%9d%98%eb%8f%84%eb%90%9c-%ea%b2%bd%ec%9a%b0" class="header-anchor"&gt;&lt;/a&gt;primitive와 박싱이 의도된 경우
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// int&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Integer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;성능이나 null 가능성이 중요한 코드라면 의도를 명시하는 편이 안전하다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;&lt;a href="#%eb%a7%88%eb%ac%b4%eb%a6%ac" class="header-anchor"&gt;&lt;/a&gt;마무리
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;var&lt;/code&gt;는 &amp;ldquo;타입 적기 귀찮을 때 쓰는 dynamic 변수&amp;quot;가 아니라 &amp;ldquo;컴파일러가 우변 보고 타입을 채워주는 단축 표기&amp;quot;다. 동작이 다르니 사용 경계도 다르다.&lt;/p&gt;</description></item><item><title>Stream.toList()와 collect(toList())는 같지 않다</title><link>https://monkshark.github.io/p/stream-tolist-vs-collect/</link><pubDate>Sat, 02 May 2026 00:00:00 +0000</pubDate><guid>https://monkshark.github.io/p/stream-tolist-vs-collect/</guid><description>&lt;p&gt;Java 16에서 추가된 &lt;code&gt;Stream.toList()&lt;/code&gt;. 기존 &lt;code&gt;collect(Collectors.toList())&lt;/code&gt;보다 짧아서 무심코 일괄 치환했다가 &lt;code&gt;UnsupportedOperationException&lt;/code&gt;을 만나는 경우가 있다.&lt;/p&gt;
&lt;h2 id="결론부터"&gt;&lt;a href="#%ea%b2%b0%eb%a1%a0%eb%b6%80%ed%84%b0" class="header-anchor"&gt;&lt;/a&gt;결론부터
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;메서드&lt;/th&gt;
 &lt;th&gt;반환 List 변경 가능 여부&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Stream.toList()&lt;/code&gt; (Java 16+)&lt;/td&gt;
 &lt;td&gt;불가능 (immutable)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Collectors.toList()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;가능 (mutable, 일반적으로 ArrayList)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;Collectors.toUnmodifiableList()&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;불가능 (immutable)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="코드로-비교"&gt;&lt;a href="#%ec%bd%94%eb%93%9c%eb%a1%9c-%eb%b9%84%ea%b5%90" class="header-anchor"&gt;&lt;/a&gt;코드로 비교
&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// UnsupportedOperationException&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;y&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="na"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Collectors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;z&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// OK&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;이름과 결과는 비슷하지만 동작이 다르다.&lt;/p&gt;
&lt;h2 id="왜-다른가"&gt;&lt;a href="#%ec%99%9c-%eb%8b%a4%eb%a5%b8%ea%b0%80" class="header-anchor"&gt;&lt;/a&gt;왜 다른가
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Collectors.toList()&lt;/code&gt;의 명세에는 &amp;ldquo;반환 리스트의 type, mutability, serializability, thread-safety는 보장하지 않는다&amp;quot;라고 적혀 있다. 다만 실제 구현이 오랜 기간 &lt;code&gt;ArrayList&lt;/code&gt;였고, 사람들이 그 동작에 의존해서 add를 호출해 왔다. 코드베이스 곳곳에 mutable 가정이 박혀 있는 상태다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Stream.toList()&lt;/code&gt;는 새로 추가되면서 처음부터 immutable이라고 명시했다. 명세대로 변경 메서드는 던진다.&lt;/p&gt;
&lt;h2 id="어떻게-갈아끼울지"&gt;&lt;a href="#%ec%96%b4%eb%96%bb%ea%b2%8c-%ea%b0%88%ec%95%84%eb%81%bc%ec%9a%b8%ec%a7%80" class="header-anchor"&gt;&lt;/a&gt;어떻게 갈아끼울지
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;결과를 그대로 읽기만 하면 &lt;code&gt;Stream.toList()&lt;/code&gt;가 낫다. 짧고 의도(불변)도 명확하다.&lt;/li&gt;
&lt;li&gt;이후 &lt;code&gt;add&lt;/code&gt; / &lt;code&gt;remove&lt;/code&gt; / 정렬 등 변경이 필요하면 &lt;code&gt;collect(Collectors.toList())&lt;/code&gt; 또는 &lt;code&gt;new ArrayList&amp;lt;&amp;gt;(stream.toList())&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;명시적으로 불변을 보장하고 싶으면 &lt;code&gt;Collectors.toUnmodifiableList()&lt;/code&gt; 또는 &lt;code&gt;List.copyOf(...)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="마무리"&gt;&lt;a href="#%eb%a7%88%eb%ac%b4%eb%a6%ac" class="header-anchor"&gt;&lt;/a&gt;마무리
&lt;/h2&gt;&lt;p&gt;리팩토링하면서 IDE 일괄 변환으로 &lt;code&gt;.collect(Collectors.toList())&lt;/code&gt;를 &lt;code&gt;.toList()&lt;/code&gt;로 모두 바꿨다가, mutable에 의존한 코드가 한참 후 단위 테스트에서 깨지는 경우가 있다. 같은 이름이라도 명세가 다르면 결과도 다르다.&lt;/p&gt;</description></item></channel></rss>