{"componentChunkName":"component---src-templates-post-template-jsx","path":"/history/posts/2020-10-04--003--03","result":{"data":{"site":{"siteMetadata":{"title":"Blog by Eunyoung","subtitle":"작업 기록 블로그","copyright":"© All rights reserved.","author":{"name":"EunYoung","twitter":"#"},"disqusShortname":"","url":"https://ssongey.github.io"}},"markdownRemark":{"id":"1bdfb343-8a99-507b-b28f-a6d4c883402c","html":"<h2>아이템3) private 생성자나 열거 타입으로 싱글턴임을 보증하라</h2>\n<p>싱글턴(Singleton)</p>\n<ul>\n<li>인스턴스를 오직 하나만 생성할 수 있는 클래스</li>\n<li>함수와 같은 무상태(stateless) 객체나 설계상 유일해야 하는 시스템 컴포넌트에 사용</li>\n</ul>\n<h2>싱글턴을 만드는 방법 3가지</h2>\n<h3>1. public static final 필드 방식</h3>\n<ul>\n<li>예외: reflection API 인 AccessibleObject.setAccessible을 사용하여 private 생성자 호출 가능\n이를 방어하기 위해 생성자를 수정하여 두번째 객체가 생성되려 할 떄 예외를 던지게 한다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Elvis</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Elvis</span> INSTANCE <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Elvis</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">private</span> <span class=\"token class-name\">Elvis</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">leaveTheBuilding</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>2. public static method 방식</h3>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">Elvis</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token class-name\">Elvis</span> INSTANCE<span class=\"token punctuation\">;</span>\n  <span class=\"token keyword\">private</span> <span class=\"token class-name\">Elvis</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token function\">getInstance</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token keyword\">return</span> INSTANCE<span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\n\n  <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">leaveTheBuilding</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h4>1,2번의 예외</h4>\n<ul>\n<li>직렬화된 인스턴스를 역직렬화할 때마다 새로운 인스턴스가 생성<br>\n— 두번째 객체가 생성될때 예외를 던져도?? 테스트 해보기</li>\n<li>\n<p>이를 방지하기 위해 인스턴스 필드에 transient 키워드를 선언하고 readResolve 메서드를 생성한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">private</span><span class=\"token operator\">/</span><span class=\"token keyword\">public</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">final</span> <span class=\"token keyword\">transient</span> <span class=\"token class-name\">Elvis</span> INSTANCE<span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// 싱글턴임을 보장해주는 메서드, 역직렬화시 호출</span>\n<span class=\"token keyword\">public</span> <span class=\"token class-name\">Object</span> <span class=\"token function\">readResolve</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token keyword\">return</span> INSTANCE <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span> </code></pre></div>\n</li>\n</ul>\n<h5>참고</h5>\n<ul>\n<li><a href=\"https://nesoy.github.io/articles/2018-04/Java-Serialize\">직렬화/역직렬화</a></li>\n<li><a href=\"https://nesoy.github.io/articles/2018-06/Java-transient\">Java transient</a></li>\n</ul>\n<h3>3. Enum 방식</h3>\n<ul>\n<li>public 필드 방식과 비슷하지만 더 간결하고 위의 예외에 대한 방어가 다 된다.</li>\n<li>대부분 상황에서 원소가 하나뿐인 열거 타입이 싱글턴을 만드는 가장 좋은 방법이다.</li>\n<li>상속(extends) 이 필요한 경우 이 방법은 사용 할 수 없다. (implements 는 가능)</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">enum</span> <span class=\"token class-name\">Elvis</span> <span class=\"token punctuation\">{</span>\n   INSTANCE<span class=\"token punctuation\">;</span>\n   <span class=\"token keyword\">public</span> <span class=\"token keyword\">void</span> <span class=\"token function\">leaveTheBuilding</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">.</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>","fields":{"tagSlugs":["/tags/책리뷰/","/tags/이펙티브자바/"],"slug":"/history/posts/2020-10-04--003--03"},"frontmatter":{"title":"[책리뷰/Effective Java] 객체 생성과 파괴","tags":["책리뷰","이펙티브자바"],"date":"2020-10-04","description":"아이템3) private 생성자나 열거 타입으로 싱글턴임을 보증하라"}}},"pageContext":{"slug":"/history/posts/2020-10-04--003--03"}},"staticQueryHashes":[]}