<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>pungjoo</title>
    <link>https://b.pungjoo.com/</link>
    <description>..</description>
    <language>ko</language>
    <pubDate>Wed, 10 Jun 2026 11:49:21 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>pungjoo.kim</managingEditor>
    <item>
      <title>Static final fields(primitive or String type) 사용 주의</title>
      <link>https://b.pungjoo.com/entry/Static-final-fieldsprimitive-or-String-type-%EC%82%AC%EC%9A%A9-%EC%A3%BC%EC%9D%98</link>
      <description>&lt;p&gt;&lt;em&gt;’Foo.class’에 상수를 정의하고 'Bar.class’에서 ‘Foo.class’에서 정의한 상수를 사용하고 있다.      &lt;br /&gt;‘Foo.class’에 정의된 상수를 변경 및 컴파일 했을 때 'B.class’는 재컴파일하지 않고 ‘Foo.class’에서 변경한 상수에 대한 영향을 받아야 한다.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h3&gt;&lt;strong&gt;&lt;em&gt;1. 들어 가며.. &lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;  &lt;p&gt;변하지 않는 값을 '상수(constant)'라고 합니다. 말 그대로 변할 수 없는 값입니다. 예를 들어 long type의 값인 100L이라는 상수를 선언하고자 한다면 통상 다음과 같이 선언 합니다. &lt;/p&gt;  &lt;p&gt;final static public long = 100L; &lt;/p&gt;  &lt;p&gt;그리고 통상적으로 상수들은 집합체인 상수 class에 모아둡니다. 이렇게 하는 이유는 크게 두가지 사유가 있습니다. &lt;/p&gt;  &lt;p&gt;1. 여기 저기 흩어져 있을 경우 수정하려 하면 많은 class를 찾아서 수정해야 하므로 불편함.    &lt;br /&gt;2. 1번 같이 한 곳에 모아 두고 변경이 있을 경우 모아둔 class만 컴파일해도 참조하는 class를 재컴파일하지 않고 runtime시에 영향을 받기 위해. &lt;/p&gt;  &lt;p&gt;그러나 위와 같이 ‘final static'으로 선언된 ‘primitive / String’ type은 생각처럼 작동하지 않습니다. &lt;/p&gt;  &lt;p&gt;첨부된 ‘The Java Language Specification, Third Edition’에서 field에 대해서 부분적으로 많은 부분에서 설명하고 있습니다. 그 중에 다음과 같은 부분을 발췌했습니다. langspe-3.0.pdf / 348~349page ( Adobe reader 382~383 page) &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The best way to avoid problems with 'inconstant constants' in widely-distributed code is to declare as compile time constants only values which truly are unlikely ever to change. Other than for true mathematical constants, we recommend that source code make very sparing use of class variables that are declared static and final. If the read-only nature of final is required, a better choice is to declare a private static variable and a suitable accessor method to get its value. Thus we recommend:      &lt;br /&gt;private static int N;       &lt;br /&gt;public static int getN() { return N; }       &lt;br /&gt;rather than:       &lt;br /&gt;public static final int N = ...;       &lt;br /&gt;There is no problem with:       &lt;br /&gt;public static int N = ...;       &lt;br /&gt;if N need not be read-only. We also recommend, as a general rule, that only truly constant values be declared in interfaces.We note, but do not recommend, that if a field of primitive type of an interface may change, its value may be expressed idiomatically as in:       &lt;br /&gt;interface Flags {       &lt;br /&gt;boolean debug = new Boolean(true).booleanValue();       &lt;br /&gt;}       &lt;br /&gt;insuring that this value is not a constant. Similar idioms exist for the other primitive types. One other thing to note is that static final fields that have constant values (whether of primitive or String type) must never appear to have the default initial value for their type (§4.12.5). This means that all such fields appear to be initialized first during class initialization (§8.3.2.1, §9.3.1, §12.4.2).&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. 현실&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;다음과 같이 Constants와 Bar가 있습니다. Bar는 Constants에 정의된 Foo를 참조합니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none; &quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 511px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/172283474FC97BCB15&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F172283474FC97BCB15&quot; width=&quot;511&quot; height=&quot;366&quot; filename=&quot;final-static-01.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;이때 Constants의 Foo를 변경하고 Constants만 컴파일 후에 실행하면 어떻게 될까요?&amp;nbsp;&lt;br /&gt;다음은 &lt;em&gt;‘Foo =100L;’을 ‘Foo = 500L;’&lt;/em&gt;으로 변경한 결과 입니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none; &quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 511px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/1263EE3C4FC97BEE0C&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F1263EE3C4FC97BEE0C&quot; width=&quot;511&quot; height=&quot;366&quot; filename=&quot;final-static-02.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;예측으로는 value가 '525'가 나와야 합니다만 '125'가 나옵니다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;과연 어떻게 컴파일되었기에 그럴까요? 해서&amp;nbsp;디컴파일해서 내부를 보겠습니다.&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none; &quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 559px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/194F01374FC97C1D11&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F194F01374FC97C1D11&quot; width=&quot;559&quot; height=&quot;390&quot; filename=&quot;final-static-03.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;우리가 원하는 결과는 &lt;strong&gt;&lt;em&gt;'long foo = Constants.Foo + 25L;'&lt;/em&gt;&lt;/strong&gt; 이라 생각 했지만, &lt;strong&gt;&lt;em&gt;'long l = 125L;'&lt;/em&gt;&lt;/strong&gt;로&amp;nbsp; 컴파일 되어 있네요.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. 이유&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;‘primitive/String’ type에 final static 이 선언되면 컴파일시에 분석기가 상수로 판단해 위 처럼 참조로 컴파일하지 않고 정적으로 값을 넣어 주게 됩니다. &lt;/p&gt;  &lt;p&gt;따라서 위와 같은 현상을 피하려면 final을 제거해 주면 되나, 애초에 상수라는 것은 runtime/컴파일시 어느 곳에서도 변경을 가할 수 없게 하기 위해서 final을 선언해 주기 때문에 근본적인 해결 책은 되지 못 합니다. &lt;/p&gt;  &lt;p&gt;해서 가급적이면 primitive type을 사용하지 않고 object type을 사용해야 합니다.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;final static public long Foo = 100L; &lt;/p&gt;    &lt;p&gt;을 다음과 같이 &lt;/p&gt;    &lt;p&gt;final static public long Foo = &lt;font color=&quot;#ff0000&quot;&gt;new Long(100L).longValue();&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;br /&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;4. 방안&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: left; clear: none; float: none; &quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 559px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/1144CD344FC97C4617&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F1144CD344FC97C4617&quot; width=&quot;559&quot; height=&quot;618&quot; filename=&quot;final-static-04.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;위와 같이 변경하면 Constants만 변경하고 컴파일하면 원하는 결과를 얻게 됩니다.    &lt;br /&gt;주의 할 부분이 하나 있습니다. String type은 object type이 맞지만 다음과 같이 해야 합니다.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;final static public String MSG = “메시지”; &lt;/p&gt;    &lt;p&gt;를 다음과 같이 &lt;/p&gt;    &lt;p&gt;final static public String MSG = new String( “메시지&quot; );&lt;/p&gt;    &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;@&lt;/p&gt;</description>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/39</guid>
      <comments>https://b.pungjoo.com/entry/Static-final-fieldsprimitive-or-String-type-%EC%82%AC%EC%9A%A9-%EC%A3%BC%EC%9D%98#entry39comment</comments>
      <pubDate>Mon, 23 Apr 2012 11:25:15 +0900</pubDate>
    </item>
    <item>
      <title>작성중 - 깨지는 한글..</title>
      <link>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-%EA%B9%A8%EC%A7%80%EB%8A%94-%ED%95%9C%EA%B8%80</link>
      <description>&lt;div&gt;
0. 들어 가면서&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
꽤나 오래전부터 한글 깨짐에 대한 질문을 1년에 서너 차례 받곤 합니다. &amp;nbsp;한글이 깨져 보이는데 영향을 주는 요인으로는 'font'와 언어적인 'encoding type' 또는 'protocol'에 대한 이해 부족에서 비롯합니다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
web page의 경우&lt;/div&gt;
&lt;div&gt;
x. code에 기술된 한글은 깨지지 않는 것 같으나 database에서 얻은 값은 깨지는 것 같다.&lt;/div&gt;
&lt;div&gt;
x. code에 기술된 한글과 database에서 얻어 값은 잘 보이나 사용자가 입력한 값은 깨지는 것 같다.&lt;/div&gt;
&lt;div&gt;
x. code에 기술된 한글은 깨지고 datatbase에 얻은 값은 깨지지 않는다&lt;/div&gt;
&lt;div&gt;
x. 등등...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
1. 준비운동&lt;/div&gt;
&lt;div&gt;
우리는 한국 사람이고 한국어를 모국어 사용합니다. 해서 주변에 있는 분들과 대화를 할때 '자 이제 부터 내가 하는 말은 한국어야.. 영어 아니다..'라고 시작하지 않습니다. 그냥 자연스럽게 말을 합니다. 그런데 요즘은 국제화 사회다 어떻다 합니다. 해서 외국인들과 대화하게 되면 의례 우리네들은 그네들의 언어에 부합되게 말을 합니다. '자 이제 부터 영어로 말할께..'라고 말하지 않고 말입니다. 그런데 재미있는 것은 영어권 사람이 한국에 와서 모르는 한국 사람 잡고 말 합니다. ' Can you speak English?'. 하긴 그네들 말로 하긴 하네요. 그래도 물어 봐 주네요. '내가 앞으로 영어로 말할건데 너 영어 할수 있냐?'라는 생각으로다...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
우리네들이 만들어 가는 code라는 것은 문자열에 불과 합니다. 이는 정확히 말하면 byte의 나열에 불과합니다. (bit 제외) 한국 사람에게는 한글이 의미 있고 영어권 사람에게는 영어가 의미가 있듯이 이 byte의 나열은 의미를 부여 받을 수 있는 곳에서 비롯서 byte의 나열이 문자열이 되고 그 문자열이 code가 됩니다. data와 information의 차이처럼..&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
정리하면&lt;/div&gt;
&lt;div&gt;
우리는 다양한 언어권에 살지 않기 때문에 의례적으로 한가지 언어로 규정해 버립니다. 영어권자를 보면 우리네들은 의례 '왜 그런지 모르겠지만 / 내 나라에서' 그네들의 언어로 말해 주려 합니다. 우리네들은 영어권 나라를 여행하면서 '왜 그런지 모르겠지만/ 그네 나라에서' 그네들의 언어로 말해 주려 합니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이 같이 컴퓨터라는 언어에서도 적극적으로 상대방을 배려하면서 그가 알아 듣게 말해 줘야 합니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
2. java 넌 그래서 무슨 언어냐..(encoding)&lt;/div&gt;
&lt;div&gt;
간단한 실험을 해 봅시다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/125130404F2240522A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F125130404F2240522A&quot; width=&quot;553&quot; height=&quot;343&quot; alt=&quot;&quot; filename=&quot;sample1-0.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
o/s의 lang는 utf-8이고 source도 utf-8로 작성되었고 o/s lang의 utf-8에서 컴파일했고 o/s lang utf-8에서 실행을 했습니다.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그냥 컴파일 하고 실행했다고 하면 될 것을 '무슨 encoding type으로 작성되었고 무슨 encoding에서 컴파일했고 무슨 encoding에서 실행했다'고 &amp;nbsp;복잡하게 기술했습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
자.. 그럼 o/s lang가 utf-8인 부분을 &amp;nbsp;euc-kr(ko_KR)로 변경해 &amp;nbsp;실행해 보겠습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/18739A414F2240770D&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F18739A414F2240770D&quot; width=&quot;649&quot; height=&quot;367&quot; alt=&quot;&quot; filename=&quot;sample1-1.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
'나는 한글이다' 부분이 깨졌네요.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
왜 깨졌을 까요? 정말 깨졌을까요?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/12054C3E4F22409530&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F12054C3E4F22409530&quot; width=&quot;649&quot; height=&quot;367&quot; alt=&quot;&quot; filename=&quot;sample1-2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
단지 console의 '문자 인코딩 설정'을 변경하니 정상적으로 보입니다. 더 복잡합니다. 이건 또 뭘까요?..&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
이 질문에 대한 근본적인 답은 후에...&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
3. jvm에서 벗어난 data를 읽기&lt;/div&gt;
&lt;div&gt;
jvm을 벗어난 file의 내용일 읽어 console에 표기 하는 내용입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/154A8D404F2240B830&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F154A8D404F2240B830&quot; width=&quot;553&quot; height=&quot;523&quot; alt=&quot;&quot; filename=&quot;DataReader1-0.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
console의 문자인코딩은 'utf-8'입니다.&lt;/div&gt;
&lt;div&gt;
그럼 위 내용중에 utf-8로 작성된 '문자열'이 아닌 euc-kr로 작성된 '문자열'로 확인해 보겠습니다&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/192202454F2240D533&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F192202454F2240D533&quot; width=&quot;613&quot; height=&quot;391&quot; alt=&quot;&quot; filename=&quot;DataReader1-1.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
위와 같이 console의 '문자 인코딩 설정'의 차이로 깨질 수 있으니 console 인코딩 까지 euc-kr로 해 보겠습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/11486B3F4F22411717&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F11486B3F4F22411717&quot; width=&quot;613&quot; height=&quot;391&quot; alt=&quot;&quot; filename=&quot;DataReader1-2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그러나 더 알수 없는 형태로 보입니다. &amp;nbsp;(cat 부분은 정상으로 보이네요.)&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그럼 DataReader1.java의 부분을 다음과 같이 수정하고 다시 해 봅시다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
// InputStreamReader isr = new InputStreamReader( fis );&lt;/div&gt;
&lt;div&gt;
InputStreamReader isr = new InputStreamReader( fis , args[1]);&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/1206AE3D4F22414313&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F1206AE3D4F22414313&quot; width=&quot;613&quot; height=&quot;523&quot; alt=&quot;&quot; filename=&quot;DataReader1-3.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
참고로 console의 '문자 &amp;nbsp;인코딩 설정'은 utf-8입니다. &amp;nbsp;parameter로 'euc-kr'을 넣으니 정상으로 나옵니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
왜 그럴까요?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
우선 euc-kr.txt를 hexdump로 해서 byte로 표현해 보면 아래와 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/172DA43E4F22415D0E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F172DA43E4F22415D0E&quot; width=&quot;511&quot; height=&quot;163&quot; alt=&quot;&quot; filename=&quot;hexdump1-0.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
그럼 java로 euc-kr.txt를 &amp;nbsp;byte 단위로 읽어 hexdump 처럼 출력해 보면&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/2063BA404F2241A920&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F2063BA404F2241A920&quot; width=&quot;613&quot; height=&quot;739&quot; alt=&quot;&quot; filename=&quot;DataReader2-0.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
byte 단위로 보면 깨진 부분이 없지만 new String 해서 문자열화해서 찍어 보니 한글이 깨집니다.&lt;br /&gt;
그럼 다음과 같이 해 보겠습니다.&lt;br /&gt;
&lt;div&gt;
//System.out.println( new String( baos.toByteArray() ) );&lt;/div&gt;
System.out.println( new String( baos.toByteArray() , args[1] ) );&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/135A5C414F2241DB28&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F135A5C414F2241DB28&quot; width=&quot;613&quot; height=&quot;739&quot; alt=&quot;&quot; filename=&quot;DataReader2-1.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
참고로 utf-8도 해 봅시다.&lt;br /&gt;
&lt;p style=&quot;margin:0&quot;&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/18625D4C4F22453F27&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F18625D4C4F22453F27&quot; width=&quot;613&quot; height=&quot;295&quot; alt=&quot;&quot; filename=&quot;DataReader2-2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;br /&gt;&lt;br /&gt;
어쩌구 저쩌구 해서 쩌구 하다..&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;</description>
      <category>JAVA</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/38</guid>
      <comments>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-%EA%B9%A8%EC%A7%80%EB%8A%94-%ED%95%9C%EA%B8%80#entry38comment</comments>
      <pubDate>Fri, 27 Jan 2012 15:20:03 +0900</pubDate>
    </item>
    <item>
      <title>작성중 - toString()</title>
      <link>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-toString</link>
      <description>&lt;div&gt;
&lt;div&gt;
0. 들어가면서&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
통상 객체의 필드의 내용을 확인 하는 용도로 System.out.println( someClass.toString() ); 을 많이 이용합니다.&lt;/div&gt;
&lt;div&gt;
그러나 toString을 Override를 하지 않으면 'className@hashcode' 값이됩니다.&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
1. 준비 운동&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(238, 238, 238); border-right-color: rgb(238, 238, 238); border-bottom-color: rgb(238, 238, 238); border-left-color: rgb(238, 238, 238); background-color: rgb(238, 238, 238); padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; &quot;&gt;
&lt;pre&gt;package info.yeonwoo.edu;

public class User {
	
	private String	name;
	private int	age;
	private String	address;
	
	public String getName() {
		return name;
	}
	
	public void setName( String name ) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge( int age ) {
		this.age = age;
	}
	
	public String getAddress() {
		return address;
	}
	
	public void setAddress( String address ) {
		this.address = address;
	}
	
	public static void main( String... args ) {

		User user = new User();
		user.setName( &quot;pungjoo.kim&quot; );
		user.setAddress( &quot;우리별.&quot; );
		user.setAge( 35 );
		
		System.out.println( user );
		
	}
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
결과는 다음과 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
info.yeonwoo.edu.User@19f953d&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
2. toString method를 Override.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
일반적으로 위와 같은 경우 toString을 Override를 해 원하는 형태로 만들어 줍니다. &amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(238, 238, 238); border-right-color: rgb(238, 238, 238); border-bottom-color: rgb(238, 238, 238); border-left-color: rgb(238, 238, 238); background-color: rgb(238, 238, 238); padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; &quot;&gt;
&lt;pre&gt;	@Override
	public String toString() {

		StringWriter sw = new StringWriter();
		PrintWriter out = new PrintWriter( sw );
		
		out.println( super.toString() + &quot; [&quot; );
		
		out.print( &quot;\t&quot; );
		out.println( &quot;name : &quot; + getName() );
		out.print( &quot;\t&quot; );
		out.println( &quot;address : &quot; + getAddress() );
		out.print( &quot;\t&quot; );
		out.println( &quot;age : &quot; + getAge() );
		out.println( &quot;]&quot;);
		out.println();
		
		return sw.toString();
		
	}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
결과는 다음과 같습니다.&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(238, 238, 238); border-right-color: rgb(238, 238, 238); border-bottom-color: rgb(238, 238, 238); border-left-color: rgb(238, 238, 238); background-color: rgb(238, 238, 238); padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; &quot;&gt;
&lt;pre&gt;info.yeonwoo.edu.User@1eed786 [
	name : pungjoo.kim
	address : 우리별.
	age : 35
]
&lt;/pre&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
3. 매번 모든 class의 toString을&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre; &quot;&gt;Override 하고 싶지 않고..&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre; &quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre; &quot;&gt;&lt;div class=&quot;txc-textbox&quot; style=&quot;border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(238, 238, 238); border-right-color: rgb(238, 238, 238); border-bottom-color: rgb(238, 238, 238); border-left-color: rgb(238, 238, 238); background-color: rgb(238, 238, 238); padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; &quot;&gt;
&lt;pre&gt;package info.yeonwoo.edu;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

public abstract class ToString {
	
	public String toString() {

		StringWriter sw = new StringWriter();
		PrintWriter out = new PrintWriter( sw, true );
		
		out.println( super.toString() + &quot; [&quot; );
		Method[] methods = this.getClass().getMethods();
		
		for ( Method method : methods ) {
			
			if ( ( method.getName().startsWith( &quot;get&quot; ) || method.getName().startsWith( &quot;is&quot; ) ) &amp;amp;&amp;amp; !method.getName().equals( &quot;getClass&quot; )
					&amp;amp;&amp;amp; method.getParameterTypes().length == 0 ) {
				
				if ( method.getName().startsWith( &quot;get&quot; ) ) {
					out.print( &quot;\t&quot; + method.getName().substring( 3 ) + &quot; : &quot; );
				}
				else {
					out.print( &quot;\t&quot; + method.getName().substring( 2 ) + &quot; : &quot; );
				}
				
				try {
					out.println( method.invoke( this ) );
				}
				catch ( Exception e ) {
				}
				
			}
			
		}
		
		out.println( &quot;]&quot; );
		
		return sw.toString();
		
	}
	
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font class=&quot;Apple-style-span&quot; face=&quot;monospace&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;추상 class를 하나 만들고.&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font class=&quot;Apple-style-span&quot; face=&quot;monospace&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font class=&quot;Apple-style-span&quot; face=&quot;monospace&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;본래 source를 다음과 같이 변경합니다.&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font class=&quot;Apple-style-span&quot; face=&quot;monospace&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;&lt;div class=&quot;txc-textbox&quot; style=&quot;border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-color: rgb(238, 238, 238); border-right-color: rgb(238, 238, 238); border-bottom-color: rgb(238, 238, 238); border-left-color: rgb(238, 238, 238); background-color: rgb(238, 238, 238); padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px; &quot;&gt;
&lt;pre&gt;package info.yeonwoo.edu;

public class User &lt;font class=&quot;Apple-style-span&quot; color=&quot;#7293FA&quot;&gt;&lt;b&gt;extends ToString&lt;/b&gt;&lt;/font&gt; {
	
	private String	name;
	private int	age;
	private String	address;
	
	public String getName() {
		return name;
	}
	
	public void setName( String name ) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge( int age ) {
		this.age = age;
	}
	
	public String getAddress() {
		return address;
	}
	
	public void setAddress( String address ) {
		this.address = address;
	}
	
	public static void main( String... args ) {

		User user = new User();
		user.setName( &quot;pungjoo.kim&quot; );
		user.setAddress( &quot;우리별.&quot; );
		user.setAge( 35 );
		
		System.out.println( user.toString() );
		
	}
}&lt;/pre&gt;&lt;/div&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font class=&quot;Apple-style-span&quot; face=&quot;monospace&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: pre;&quot;&gt;결과는 Method를 &lt;/span&gt;&lt;/font&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre; &quot;&gt;Override한 것과 비슷합니다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre; &quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace; white-space: pre; &quot;&gt;어쩌구 저쩌구 해서 저쩌구 하지 뭐&lt;/span&gt;&lt;/div&gt;
&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot;&gt;</description>
      <category>JAVA</category>
      <category>toString</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/24</guid>
      <comments>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-toString#entry24comment</comments>
      <pubDate>Fri, 9 Jul 2010 16:46:17 +0900</pubDate>
    </item>
    <item>
      <title>작성중 - unmodifiable</title>
      <link>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-unmodifiable</link>
      <description>0. 들어가면서
&lt;DIV&gt;Collections class에는&amp;nbsp;unmodifiable류의 method가 존재합니다. 즉, 특정상황에 return되는 객체의 특정 method는 사용하지 못 하도록 강제하고 싶을 때 사용합니다.&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;1. 준비 운동&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
&lt;br /&gt;public class WarmingUp {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;private static List&amp;lt;String&amp;gt;&lt;STRING&gt; getData() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ArrayList&amp;lt;String&amp;gt;&lt;STRING&gt; data = new ArrayList&amp;lt;String&amp;gt;&lt;STRING&gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.add(&quot;pungjoo&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.add(&quot;siyeon&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.add(&quot;siwoo&quot;);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;FONT class=Apple-style-span color=#e31600&gt;return data;&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; List&amp;lt;String&amp;gt;&lt;STRING&gt; data = getData();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; data.add(&quot;jihyun&quot;);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; System.out.println( data);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/STRING&gt;&lt;/STRING&gt;&lt;/STRING&gt;&lt;/STRING&gt;&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;결과는&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;[pungjoo, siyeon, siwoo, jihyun]&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;그럼 위 붉은 색 LINE을... 이렇게~~~~~~~&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;
import java.util.Collections;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
&lt;br /&gt;public class WarmingUp {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; private static List&amp;lt;String&amp;gt;&lt;STRING&gt; getData() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;ArrayList&amp;lt;String&amp;gt;&lt;STRING&gt;&amp;nbsp;data = new ArrayList&amp;lt;String&amp;gt;&lt;STRING&gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;data.add(&quot;pungjoo&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;data.add(&quot;siyeon&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;data.add(&quot;siwoo&quot;);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;FONT class=Apple-style-span color=#e31600&gt;return Collections.unmodifiableList(data);&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;List&amp;lt;String&amp;gt;&lt;STRING&gt; data = getData();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;data.add(&quot;jihyun&quot;);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(data);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/STRING&gt;&lt;/STRING&gt;&lt;/STRING&gt;&lt;/STRING&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;결과는&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;&lt;FONT class=Apple-style-span color=#e31600&gt;Exception in thread &quot;main&quot;&lt;/FONT&gt; java.lang.UnsupportedOperationException&lt;br /&gt;
&lt;FONT class=Apple-style-span color=#e31600&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;at java.util.Collections$UnmodifiableCollection.add&lt;/FONT&gt;(Collections.java:1018)&lt;br /&gt;
&lt;FONT class=Apple-style-span color=#e31600&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;at info.yeonwoo.edu.WarmingUp.main&lt;/FONT&gt;(WarmingUp.java:23)&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;지원하지 않는 ~~&lt;br /&gt;

&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;2.&amp;nbsp;단순히 생각해 보면 다음과 같이 해 볼 수 있겠죠.&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;뼈대를 만들어 봅시다..&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;public class Foo {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; private String name;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public String getName() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return name;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public void setName(String name) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.name = name;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;뼈대를 실행해 봅시다.&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;public class Bar {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;public static Foo getData() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Foo foo = new Foo();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;FONT class=Apple-style-span color=#e31600&gt;return foo;&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Foo foo = getData();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System.out.println( foo.getName());&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foo.setName(&quot;siyeon&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System.out.println( foo.getName());&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;결국은 붉은 색 LINE을 어떻게하면 될 듯 한데...&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;음 단순하게 이런 방식은 어떨까?&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;public static Foo getData() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;FONT class=Apple-style-span color=#e31600&gt;final&lt;/FONT&gt; Foo foo = new Foo();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;FONT class=Apple-style-span color=#e31600&gt;Foo ret = new Foo() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;@Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public void setName(String name) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; throw new UnsupportedOperationException();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;@Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public String getName() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return foo.getName();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; };&lt;/FONT&gt; &lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; return ret;&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;결과 &lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;pungjoo&lt;br /&gt;
Exception in thread &quot;main&quot; java.lang.UnsupportedOperationException&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; at info.yeonwoo.edu.Bar$1.setName(Bar.java:14)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; at info.yeonwoo.edu.Bar.main(Bar.java:32)&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;원하는 결과는 나왔으나 모든 class의 method를 override를 할 수는 없는 노릇이고...&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;어쩌구 저쩌구 얼씨구 절씨구~~~~&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;proxy?.. (&amp;nbsp;http://pungjoo.tistory.com/17 )&lt;br /&gt;
&lt;br /&gt;&lt;/DIV&gt;
&lt;DIV&gt;proxy를 사용하기 위해서는 기본조건이 객체는 항상 interface를 사용해야 합니다. &amp;nbsp;따라서 Foo class를 FooImpl로 변경하고 Foo은 interface화 합니다.&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;public interface Foo {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public String getName();&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public void setName(String name);&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;public class FooImpl implements Foo {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; private String name;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; @Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; public String getName() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return name;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; @Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; public void setName(String name) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.name = name;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;3. 이런건 어떨까?&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;import java.lang.reflect.InvocationHandler;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.lang.reflect.Proxy;&lt;br /&gt;
&lt;br /&gt;public class ObjectUnModify implements 
&lt;DIV style=&quot;DISPLAY: inline; VISIBILITY: hidden; WIDTH: auto; POSITION: absolute; HEIGHT: auto&quot;&gt;InvocationHandler&lt;/DIV&gt;InvocationHandler {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; private Object obj = null;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;private ObjectUnModify(Object obj) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.obj = obj;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;@Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (method.getName().startsWith(&quot;set&quot;)) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;FONT class=Apple-style-span color=#3058d2&gt;throw new UnsupportedOperationException();&lt;/FONT&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Method mm = obj.getClass().getMethod(method.getName(), method.getParameterTypes());&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; return mm.invoke(obj, args);&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;@SuppressWarnings( { &quot;hiding&quot;, &quot;unchecked&quot; } )&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; final public static &amp;lt;T extends Object&amp;gt;T&lt;T object=&quot;&quot; extends=&quot;&quot;&gt;&amp;nbsp;wrap(T obj) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return (T) Proxy.newProxyInstance(&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;obj.getClass().getClassLoader(),&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;obj.getClass().getInterfaces(),&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;new ObjectUnModify(obj));&lt;br /&gt;
&lt;/T&gt;&lt;T style=&quot;MARGIN-LEFT: 4em&quot; object=&quot;&quot; extends=&quot;&quot;&gt;&lt;br /&gt;
&lt;/T&gt;&lt;T object=&quot;&quot; extends=&quot;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/T&gt;&lt;/DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;이쯤에서 Test를 해 봐야겠지요?&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;public class Bar {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public static Foo getData() {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Foo foo = new FooImpl();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
&lt;br /&gt;&lt;FONT class=Apple-style-span color=#e31600&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;return ObjectUnModify.wrap(foo);&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Foo foo = getData();&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System.out.println( foo.getName());&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foo.setName(&quot;siyeon&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;System.out.println( foo.getName());&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;결과는&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: rgb(193,193,193) 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: rgb(193,193,193) 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: rgb(193,193,193) 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: rgb(193,193,193) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)&quot;&gt;pungjoo&lt;br /&gt;
Exception in thread &quot;main&quot; java.lang.UnsupportedOperationException&lt;br /&gt;
&lt;SPAN class=Apple-tab-span style=&quot;WHITE-SPACE: pre&quot;&gt;&lt;/SPAN&gt;at info.yeonwoo.edu.ObjectUnModify.invoke(ObjectUnModify.java:22) &lt;br /&gt;
&lt;SPAN class=Apple-tab-span style=&quot;WHITE-SPACE: pre&quot;&gt;&lt;/SPAN&gt;&lt;FONT class=Apple-style-span color=#e31600&gt;at $Proxy0.setName(Unknown Source) &lt;/FONT&gt;&lt;br /&gt;
&lt;SPAN class=Apple-tab-span style=&quot;WHITE-SPACE: pre&quot;&gt;&lt;/SPAN&gt;at info.yeonwoo.edu.Bar.main(Bar.java:19)&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;어쩌구 저쩌구 해서 저쩌구 어쩌구 이러다 저렇다~~&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;@&lt;/DIV&gt;&lt;/DIV&gt;
&lt;DIV style=&quot;BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; LEFT: 178px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; FONT: 13px arial, sans-serif; WIDTH: 0px; PADDING-TOP: 0px; POSITION: absolute; TOP: 962px; HEIGHT: auto; BACKGROUND-COLOR: transparent; TEXT-ALIGN: left; BORDER-RIGHT-WIDTH: 0px; background-origin: initial; background-clip: initial&quot;&gt;&lt;/DIV&gt;
&lt;DIV style=&quot;BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; LEFT: 261px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; FONT: 13px arial, sans-serif; WIDTH: 0px; PADDING-TOP: 0px; POSITION: absolute; TOP: 3928px; HEIGHT: auto; BACKGROUND-COLOR: transparent; TEXT-ALIGN: left; BORDER-RIGHT-WIDTH: 0px; background-origin: initial; background-clip: initial&quot;&gt;&lt;/DIV&gt;</description>
      <category>JAVA</category>
      <category>InvocationHandler</category>
      <category>Proxy</category>
      <category>reflection</category>
      <category>unmodifiableList</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/21</guid>
      <comments>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-unmodifiable#entry21comment</comments>
      <pubDate>Mon, 11 Jan 2010 19:13:37 +0900</pubDate>
    </item>
    <item>
      <title>작성중 - Singleton에 대한 이해.</title>
      <link>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-Singleton%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4</link>
      <description>0. 들어가면서 
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
일반적으로 singleton에 대해 설명하는 글을 보면 JVM상에 유일하게 인스턴화된 객체라고 표현합니다.&lt;/div&gt;
&lt;div&gt;
그러나 이는 엄밀히 말하면 JVM상에 classloader에 따른 유일하게 인스턴화된 객체가 맞는 표현입니다.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;strong&gt;&lt;font color=&quot;#3058d2&quot;&gt;주의 : 싱글 인스턴를 만드는 방법을 설명하는 글이 아닙니다&lt;/font&gt;&lt;/strong&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
1. 경험&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
tomcat기준으로 1개의 process(jvm)에는 기본적으로 1개의 context를 정의해 사용하나 여러개의 context를 등록해 uri path로 구분해 서비스할 수 있습니다. 이런 경우에 과연 각각 context마다 WEB-INF/classes에 놓여 있는 singleton class가 jvm하에서 유일할까요? 어쩌구 저쩌구&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
2. 프로젝트 만들기&amp;nbsp;( 편의상 이클립스 사용 )&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
다음과 같이 2개의 Java Project를 생성합니다.&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/13608B184B30917308&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F13608B184B30917308&quot; width=&quot;358&quot; height=&quot;275&quot; alt=&quot;&quot; filename=&quot;project.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
( 이미지는 Romm이네 이런....&amp;nbsp; 프로젝트 이름이 뭐 중요한가 그냥 ...) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. 추상클래스 및 구현체 작성&lt;br /&gt;
&lt;br /&gt;
00-commonRoom 프로젝트에서....&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;
public abstract class Singleton {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; abstract public void printSum();&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;
import info.yeonwoo.edu.Singleton;&lt;br /&gt;
&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicLong;&lt;br /&gt;
&lt;br /&gt;
final public class SingletonImpl extends Singleton {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; final static private SingletonImpl INSTANCE = new SingletonImpl();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; final AtomicInteger counter = new AtomicInteger();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private SingletonImpl() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void printSum() {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread t = new Thread() {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void run() {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AtomicLong sum = new AtomicLong();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int loop = 0; loop &amp;lt; 10; loop++) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.sleep(10);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (InterruptedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sum.addAndGet(counter.incrementAndGet());&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(Thread.currentThread() + &quot; : Sum = &quot; + sum.get());&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t.start();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static Singleton getInstance() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return INSTANCE;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
4. 테스트&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;
import info.yeonwoo.edu.Singleton;&lt;br /&gt;
&lt;br /&gt;
public class SingletonTest1 {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int mainLoop = 0; mainLoop &amp;lt; 5; mainLoop++) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Singleton obj =&lt;font color=&quot;#e31600&quot;&gt; &lt;/font&gt;&lt;font color=&quot;#3058d2&quot;&gt;&lt;font color=&quot;#e31600&quot;&gt;SingletonImpl.getInstance();&lt;/font&gt;&lt;br /&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj.printSum();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
결과&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
Thread[Thread-0,5,main] : Sum = 235&lt;br /&gt;
Thread[Thread-1,5,main] : Sum = 245&lt;br /&gt;
Thread[Thread-2,5,main] : Sum = 255&lt;br /&gt;
Thread[Thread-4,5,main] : Sum = 265&lt;br /&gt;
Thread[Thread-3,5,main] : Sum = 275&lt;/div&gt;
&lt;br /&gt;
위 소스에서 붉은 색 부분을 다른 형태로 &lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.net.URLClassLoader;&lt;br /&gt;
&lt;br /&gt;
public class SingletonTest2 {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) throws Exception {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int mainLoop = 0; mainLoop &amp;lt; 5; mainLoop++) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#e31600&quot;&gt; URLClassLoader uc = (URLClassLoader) ClassLoader.getSystemClassLoader();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Class clazz = uc.loadClass(&quot;info.yeonwoo.edu.SingletonImpl&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Method method = clazz.getMethod(&quot;getInstance&quot;, new Class[] {});&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Singleton obj = &lt;font color=&quot;#e31600&quot;&gt;(Singleton) method.invoke(new Object[] {}, new Object[] {});&lt;br /&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj.printSum();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
결과&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
Thread[Thread-1,5,main] : Sum = 248&lt;br /&gt;
Thread[Thread-4,5,main] : Sum = 272&lt;br /&gt;
Thread[Thread-2,5,main] : Sum = 249&lt;br /&gt;
Thread[Thread-0,5,main] : Sum = 240&lt;br /&gt;
Thread[Thread-3,5,main] : Sum = 266&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
5. 구현 클래스 및 테스트 클래스를 SingletonRoom 프로젝트로 이동&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/163AB1124B30A5395E&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F163AB1124B30A5395E&quot; width=&quot;541&quot; height=&quot;362&quot; alt=&quot;&quot; filename=&quot;move-error.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
(1)과 같이 00-commonRoom 프로젝트에서 SingletonRoom으로 클래스 파일을 옮기면 ( 이미지는 Romm이네 이런.... )&lt;br /&gt;
(2)와 같이 오류가 발생하는데 이는 SingletonRoom 프로젝트에는 info.yeonwoo.edu.Singleton.class가 없기때문입니다.&lt;br /&gt;
&lt;br /&gt;
SingletonRoom의 properties-&amp;gt; Java Build Path -&amp;gt; Projects -&amp;gt; Add -&amp;gt; 00-commonRoom 추가.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/11449C104B30A9CB9B&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F11449C104B30A9CB9B&quot; width=&quot;700&quot; height=&quot;517&quot; alt=&quot;&quot; filename=&quot;javaBuildPath.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
SingletonRoom 프로젝트로 옮긴 후 SingletonTest1 / SingletonTest2 를 각각 실행해 보세요. 결과는 동일함.&lt;br /&gt;
&lt;br /&gt;
6. 이제 하고 싶은 말을 해 보자...&lt;br /&gt;
&lt;br /&gt;
다시 00-commonRoom에 다음과 같은 Test 클래스를 만들어 보면... 위 Test2를 조금 변형 시켜서...&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;
import java.io.File;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.net.URL;&lt;br /&gt;
import java.net.URLClassLoader;&lt;br /&gt;
&lt;br /&gt;
public class SingletonTest3 {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) throws Exception {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=&quot;#e31600&quot;&gt; File file = new File(&quot;../SingletonRoom/bin/&quot;);&lt;br /&gt;
&lt;/font&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for (int mainLoop = 0; mainLoop &amp;lt; 5; mainLoop++) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; URLClassLoader uc = &lt;font color=&quot;#e31600&quot;&gt;new URLClassLoader(new URL[] { file.toURI().toURL() });&amp;nbsp;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Class clazz = uc.loadClass(&quot;info.yeonwoo.edu.SingletonImpl&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Method method = clazz.getMethod(&quot;getInstance&quot;, new Class[] {});&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Singleton obj = (Singleton) method.invoke(new Object[] {}, new Object[] {});&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj.printSum();&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
결과&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
Thread[Thread-0,5,main] : Sum = 55&lt;br /&gt;
Thread[Thread-2,5,main] : Sum = 55&lt;br /&gt;
Thread[Thread-1,5,main] : Sum = 55&lt;br /&gt;
Thread[Thread-3,5,main] : Sum = 55&lt;br /&gt;
Thread[Thread-4,5,main] : Sum = 55&lt;/div&gt;
&lt;br /&gt;
그럼 이런건 어떨까?&lt;br /&gt;
SingletonRoom 프로젝트에서&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
package info.yeonwoo.edu;&lt;br /&gt;
&lt;br /&gt;
public class SingletonTest4 {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) throws Exception {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SingletonTest3.main(null);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
결과&lt;br /&gt;

&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #cbcbcb 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px solid; BACKGROUND-COLOR: #ffffff&quot;&gt;
Thread[Thread-1,5,main] : Sum = 235&lt;br /&gt;
Thread[Thread-2,5,main] : Sum = 245&lt;br /&gt;
Thread[Thread-3,5,main] : Sum = 258&lt;br /&gt;
Thread[Thread-4,5,main] : Sum = 262&lt;br /&gt;
Thread[Thread-0,5,main] : Sum = 275&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
어쩌구 저쩌구~~~~~&lt;br /&gt;
&lt;br /&gt;
이쯤에서 디렉토리 구조를&amp;nbsp;살펴 보면..&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/194380124B30AEC893&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F194380124B30AEC893&quot; width=&quot;523&quot; height=&quot;470&quot; alt=&quot;&quot; filename=&quot;directory.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
7. 결론...&lt;br /&gt;
&lt;br /&gt;
어쩌구 저쩌구가 이래서 저래서 그렇다..&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
8. 소스&lt;/div&gt;
&lt;div&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;a href=&quot;https://t1.daumcdn.net/cfile/tistory/2042BC204B30B61187&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;https://i1.daumcdn.net/cfs.tistory/v/0/blog/image/extension/zip.gif&quot; style=&quot;vertical-align: middle;&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;Singleton-yeonwooEdu.zip&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
해당 소스를 이클립스에서 import하세요. ( general -&amp;gt; Existing Projeccts into Workspace -&amp;gt; Select archive file )&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
@&lt;/div&gt;</description>
      <category>JAVA</category>
      <category>singleton</category>
      <category>urlclassloader</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/20</guid>
      <comments>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-Singleton%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4#entry20comment</comments>
      <pubDate>Tue, 22 Dec 2009 18:18:52 +0900</pubDate>
    </item>
    <item>
      <title>작성중 - Proxy ( java.lang.reflect.Proxy )</title>
      <link>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-Proxy-javalangreflectProxy</link>
      <description>0. 들어 가면서.&lt;br /&gt;
&lt;br /&gt;
흔히들 유연성을 갖기 위해서 요즘은 interface를 작성하고 해당 interface를 implement한 본연의 class를 작성을 많이 합니다.&lt;br /&gt;
어쩌구 저저구 - 작성중...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. 준비 운동&lt;br /&gt;
&lt;br /&gt;
다음과 같은 Foo interface가 있을 경우 개발을 할 당시 초기화를 어떻게 할까?&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
public interface Foo {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public void setName( String name );&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public String getName();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public void setAddress( String address);&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public String getAddress();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
} &lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
일반적으로 다음과 같이 Foo interface를 상속해 class를 생성합니다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
public class FooImpl implements Foo {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private String name;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private String address;&lt;/div&gt;
&lt;br /&gt;

&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public String getAddress() {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
return address;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public String getName() {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
return name;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public void setAddress(String address) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
this.address = address;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
@Override&lt;br /&gt;
public void setName(String name) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
this.name = name;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;}&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
실질적으로 Foo / FooImpl을 사용해 보겠습니다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
public class FooTest {&lt;br /&gt;

&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;br /&gt;
private static void print(Foo foo) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&lt;br /&gt;
foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
foo.setAddress(&quot;pegasus&quot;);&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
System.out.println(foo.getName() + &quot; / &quot; + foo.getAddress());&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static void main(String[] args) {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
Foo foo = new FooImpl();&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&lt;br /&gt;
print(foo);&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
}&lt;/div&gt;
&lt;br /&gt;
다른 방법은 없을까요? 객체를 생성하는 방법에 있어서요...&lt;br /&gt;
여러 가지 방법이 있겠지만 우선 'anonymous class'라는 형태로 다시 Foo을 구현해 보겠습니다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
public class FooTest {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private static void print(Foo foo) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&lt;br /&gt;
foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
foo.setAddress(&quot;pegasus&quot;);&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
System.out.println(foo.getName() + &quot; / &quot; + foo.getAddress());&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public static void main(String[] args) {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
Foo foo = &lt;font color=&quot;#5c7fb0&quot;&gt;new Foo() {&lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;private String name;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;private String address;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;@Override&lt;br /&gt;
public String getAddress() {&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 16em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;return address;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;@Override&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;public String getName() {&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 16em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;return name;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;@Override&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;public void setAddress(String address) {&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 16em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;this.address = address;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;}&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;@Override&lt;br /&gt;
public void setName(String name) {&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 16em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;this.name = name;&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;};&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
print(foo);&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
흔히들 inteface는 &amp;nbsp;new 할 수 없다고 알고 있으나 위와 같이 new 가 가능합니다. 단일 블럭 안에서 사용하는 class라면 위와 같은 형태도 그리 나쁘지 않은 구조입니다. 그러나 빈번하게 객체 생성하거나 다른 블럭에서 생성하는&amp;nbsp; 것이 라면 위와 같은 형태로는 곤란하겠지요.&lt;br /&gt;
&lt;br /&gt;
어쩌구 저쩌구&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2. Proxy&lt;br /&gt;
&lt;br /&gt;
위 익명 클래스와는 다른 형태지만 느낌 상으로 비슷한 일을 하고 싶을 경우가 있습니다. method 기능인 서비스를 동적으로 만들고 싶거나 애초에 interface를 구현한 class의 method를 호출 하기 전/후에 다른 일을 하고&amp;nbsp;싶고 또는 해당 method의 내용을 말그대로 동적으로 변화를 주고 싶거나...&lt;br /&gt;
&lt;br /&gt;
&lt;font face=&quot;Courier New&quot;&gt;Proxy&lt;/font&gt; provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. &lt;br /&gt;
&lt;br /&gt;
proxy를 사용하기 위해서는 항상 interface가 있어야 합니다. implement class는&amp;nbsp;상황에 따라서 필요합니다.&lt;br /&gt;
&lt;br /&gt;
Proxy를 사용해 위 FooImpl의 기능을 비슷하게 만들어 보겠습니다. &lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.InvocationHandler;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.util.HashMap;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
public class FooProxyHandler implements InvocationHandler {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private Map&amp;lt;String, Object&amp;gt; datas = new HashMap&amp;lt;String, Object&amp;gt;();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
String methodName = method.getName();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
if (methodName.startsWith(&quot;set&quot;)) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
datas.put(methodName.substring(3), args[0]);&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
} else if (methodName.startsWith(&quot;get&quot;) &amp;amp;&amp;amp; !methodName.equals(&quot;getClass&quot;)) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
return datas.get(methodName.substring(3));&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
return null;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
위와 같이 FooProxyHandler를 만들고 기 만들었던 FooTest를 다음과 같이 수정합니다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.Proxy;&lt;br /&gt;
&lt;br /&gt;
public class FooTest {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private static void print(Foo foo) {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
foo.setAddress(&quot;pegasus&quot;);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
System.out.println(foo.getName() + &quot; / &quot; + foo.getAddress());&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public static void main(String[] args) {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
Foo foo = &lt;font color=&quot;#5c7fb0&quot;&gt;(Foo) Proxy.newProxyInstance(&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;Foo.class.getClassLoader(), new Class[] { Foo.class },&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;new FooProxyHandler() );&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
print(foo);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;

&lt;div&gt;
&lt;/div&gt;&lt;br /&gt;
3. 심화 학습....&lt;br /&gt;
&lt;br /&gt;
FooProxyHandler는 setter/getter에 평이한 형태와 단지 value를 저장하는 용도 정도의 내용이므로 단순합니다. 그러나 실제 사용되는 class는 단순하지 않죠.&lt;br /&gt;
&lt;br /&gt;
FooImpl을 그대로 사용하고 즉, 수정하지 않고 각 method를 수행하는데 있어서 얼마의 시간이 소요되는가 로그를 찍고 싶을 경우를 생각해 보겠습니다.&amp;nbsp; 그래도 시간이 걸리는 차이를 인지 하기 위해서 FooImpl의 viod setName() mehotd를 다음과 같이 변경하겠습니다. 혼돈이 없게 FooImpl을 extent한 ExtFooImpl로 작성합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
public class ExtFooImpl extends FooImpl implements Foo {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public void setName(String name) {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
try {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
java.util.Random random = new java.util.Random();&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
int sleep = random.nextInt(1000);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
Thread.sleep(sleep);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
} catch (InterruptedException e) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
super.setName(name);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
&lt;br /&gt;
FooProxyHandler를 다음과 같이 변경합니다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.InvocationHandler;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
&lt;br /&gt;
public class FooProxyHandler implements InvocationHandler {&lt;br /&gt;

&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;br /&gt;
private Foo foo = new ExtFooImpl();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
long time = System.currentTimeMillis();&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
try {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
System.out.println(&quot;&amp;gt;&amp;gt; &quot; + method.toGenericString() + &quot; start : &quot; + new Date());&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;br /&gt;
return method.invoke(foo, args);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
} finally {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
System.out.println(&quot;&amp;gt;&amp;gt; &quot; + method.toGenericString() + &quot; end&amp;nbsp;&amp;nbsp; : &quot; + &lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 16em&quot;&gt;
(System.currentTimeMillis() - time) + &quot;ms&quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
ProxyHandler는 Foo / FooImpl / ExtFooImpl / class에 종속적이므로 이 부분을 종속적이 않게 해 봅시다.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3. 끝을 향해 달려 보자..&lt;br /&gt;
&lt;br /&gt;
새로이 proxyHandler를 다음과 같이 만듭니다. FooProxyHandler와 크게 다르지는 않습니다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
import java.lang.reflect.InvocationHandler;&lt;br /&gt;
import java.lang.reflect.Method;&lt;br /&gt;
import java.lang.reflect.Proxy;&lt;br /&gt;
import java.util.Date;&lt;br /&gt;
&lt;br /&gt;
public class EduProxyHandler implements InvocationHandler {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private Object obj = null;&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private EduProxyHandler(Object obj) {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
this.obj = obj;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
@Override&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&lt;br /&gt;
long time = System.currentTimeMillis();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&amp;nbsp;try {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
System.out.println(&quot;&amp;gt;&amp;gt; &quot; + method.toGenericString() + &quot; start : &quot; + new Date());&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
return method.invoke(obj, args);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
} finally {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
System.out.println(&quot;&amp;gt;&amp;gt; &quot; + method.toGenericString() + &quot; end&amp;nbsp;&amp;nbsp; : &quot; + &lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 16em&quot;&gt;
(System.currentTimeMillis() - time) + &quot;ms&quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;public static Object newInstance(Object obj) throws IllegalArgumentException{&lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;return Proxy.newProxyInstance(obj.getClass().getClassLoader(), &lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;obj.getClass().getInterfaces(), new EduProxyHandler(obj));&lt;br /&gt;
&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;}&lt;/font&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
크게 다르지 않겠지만 Test class도 다시 만들어 봅시다.&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
public class EduProxyTest {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private static void print(Foo foo) {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
foo.setName(&quot;pungjoo&quot;);&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
foo.setAddress(&quot;pegasus&quot;);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
&amp;nbsp;System.out.println(foo.getName() + &quot; / &quot; + foo.getAddress());&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public static void main(String[] args) {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
Foo foo = (Foo) EduProxyHandler.newInstance(new ExtFooImpl());&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
print(foo);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
4. Stack trace 살펴 보기&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
java.lang.Exception: Stack trace&lt;br /&gt;
&amp;nbsp;at java.lang.Thread.dumpStack(Unknown Source)&lt;br /&gt;
&amp;nbsp;at info.yeonwoo.edu.proxy.FooImpl.dump(FooImpl.java:42)&lt;br /&gt;
&lt;font color=&quot;#e31600&quot;&gt;&amp;nbsp;at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt;
&amp;nbsp;at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)&lt;br /&gt;
&amp;nbsp;at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)&lt;br /&gt;
&amp;nbsp;at java.lang.reflect.Method.invoke(Unknown Source)&lt;br /&gt;
&amp;nbsp;at info.yeonwoo.edu.proxy.EduProxyHandler.invoke(EduProxyHandler.java:23)&lt;br /&gt;
&lt;font size=&quot;+0&quot;&gt;&lt;span style=&quot;FONT-SIZE: 9pt&quot;&gt;&amp;nbsp;at $Proxy0.dump(Unknown Source)&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;br /&gt;
&amp;nbsp;at info.yeonwoo.edu.proxy.EduProxyTest.main(EduProxyTest.java:23)&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
5. 흉내내기...&lt;br /&gt;
&lt;br /&gt;
다음과 같이 EduProxyManager를 하나 생성합니다. 단, classloader에 따른 싱글인스턴가 되므로 Thread-safe하지 않은 모습이 되므로 주의 해야 합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package info.yeonwoo.edu.proxy;&lt;br /&gt;
&lt;br /&gt;
import java.util.HashMap;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;
public class EduProxyManager {&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
final static private EduProxyManager INSTANCE = new EduProxyManager();&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;br /&gt;
private Map&amp;lt;String, Object&amp;gt; serviceStore = new HashMap&amp;lt;String, Object&amp;gt;();&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private&amp;nbsp;EduProxyManager(){&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
private void register0(String serviceName, String serviceClazz) throws IllegalArgumentException,&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
InstantiationException,&amp;nbsp;IllegalAccessException, ClassNotFoundException {&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
serviceStore.put(serviceName, &lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
EduProxyHandler.newInstance(Class.forName(serviceClazz).newInstance()));&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&amp;nbsp;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public static void register(String serviceName, String serviceClazz) throws IllegalArgumentException, &lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
InstantiationException,&amp;nbsp;IllegalAccessException, ClassNotFoundException {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 12em&quot;&gt;
INSTANCE.register0(serviceName, serviceClazz);&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;

&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
private Object getService0(String serviceName) {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
return serviceStore.get(serviceName);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
public static Object getService(String serviceName) {&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
return INSTANCE.getService0(serviceName);&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
EduProxTest를 다음과 같이 수정합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
public static void main(String[] args) throws IllegalArgumentException, InstantiationException, &lt;br /&gt;

&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
IllegalAccessException,&amp;nbsp;ClassNotFoundException {&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;br /&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;EduProxyManager.register(&quot;Foo&quot;, &quot;info.yeonwoo.edu.proxy.ExtFooImpl&quot;);&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;br /&gt;
&lt;br /&gt;
Foo foo = (Foo) &lt;font color=&quot;#5c7fb0&quot;&gt;EduProxyManager.getService(&quot;Foo&quot;);&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/font&gt;&lt;br /&gt;
print(foo);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
Classloader에 따른 싱글인스턴이므로 다음과 같은 결과에 주의를 해야 합니다.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px solid; BORDER-LEFT: #cbcbcb 1px solid; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px solid; BORDER-RIGHT: #cbcbcb 1px solid; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
public static void main(String[] args) throws IllegalArgumentException, InstantiationException, &lt;br /&gt;

&lt;div style=&quot;MARGIN-LEFT: 8em&quot;&gt;
IllegalAccessException, ClassNotFoundException {&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
EduProxyManager.register(&quot;Foo&quot;, &quot;info.yeonwoo.edu.proxy.ExtFooImpl&quot;);&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;Foo foo = (Foo) EduProxyManager.getService(&quot;Foo&quot;);&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
print(foo);&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
&lt;font color=&quot;#5c7fb0&quot;&gt;Foo foo2 = (Foo) EduProxyManager.getService(&quot;Foo&quot;);&lt;br /&gt;
&lt;/font&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;/div&gt;
&lt;div style=&quot;MARGIN-LEFT: 4em&quot;&gt;
System.out.println( foo2.getName());&lt;br /&gt;
&lt;/div&gt;
&lt;div&gt;
&amp;nbsp;&amp;nbsp;&lt;br /&gt;
}&lt;/div&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;</description>
      <category>JAVA</category>
      <category>Proxy</category>
      <category>reflection</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/17</guid>
      <comments>https://b.pungjoo.com/entry/%EC%9E%91%EC%84%B1%EC%A4%91-Proxy-javalangreflectProxy#entry17comment</comments>
      <pubDate>Fri, 21 Aug 2009 17:10:31 +0900</pubDate>
    </item>
    <item>
      <title>Transfer-Encoding: chunked VS Content-Length</title>
      <link>https://b.pungjoo.com/entry/Transfer-Encoding-chunked-VS-Content-Length</link>
      <description>&lt;P&gt;0. 들어가면서&lt;br /&gt;
&lt;br /&gt;Network에서는 전송하고자 하는 콘텐츠(&lt;FONT color=#008000&gt;content, 또는 &lt;/FONT&gt;data) 길이를&amp;nbsp;헤더에 기술하던가 콘텐츠의 끝이라고 서로간에 약속한 데이터를 마지막에 기술하던가 이도 저도 아니면 open된 stream(socket 포함)을 close를 할때 전송의 끝이라고 인식하게 됩니다.&lt;br /&gt;
&lt;br /&gt;영화를 보면 무전기를 들어 자신이 할 말이 끝났을 때 항상 끝에 '오바(over)'라고 해 자신이 할 말이 끝났음을 상대방에게 알려 줍니다. 이는 통신 규칙입니다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
1.&amp;nbsp; Content-Length&lt;br /&gt;
&lt;br /&gt;Content-Length는 응답(response)의 header에 정의 되는 것으로 요청한 내용에 대한 실제적인 결과인 body의 길이가 몇 bytes인가를 의미합니다. 클라이언트(통상 브라우져)는 헤더(header)에 정의된 Content-Length 만큼을 InputStream에서 읽게 됩니다. &lt;/P&gt;
&lt;DIV style=&quot;BORDER-BOTTOM: #c1c1c1 1px dashed; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-TOP: 10px&quot; class=txc-textbox&gt;[pungjoo@yeonwoo] $ cat Normal.java&lt;br /&gt;
&lt;br /&gt;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IOException {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PrintWriter out = response.getWriter();&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.print( &quot;data1&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;out.print( &quot;data2&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.println();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} finally {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (out != null) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.close();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;[pungjoo@yeonwoo] $&lt;/DIV&gt;
&lt;P&gt;위와 같은 /normal servlet을 호출해 보겠습니다.&lt;br /&gt;
참고로&amp;nbsp;keep-alive의 설정이 서버측면에 되어 있어서 keep-alive를&amp;nbsp;사용되지 않게 'Connection: close'를 추가했습니다. 이 부분은 HTTP/1.1 부분을 HTTP/1.0으로 하면 동일한 효과를 얻게 됩니다.&lt;/P&gt;
&lt;DIV style=&quot;BORDER-BOTTOM: #c1c1c1 1px dashed; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-TOP: 10px&quot; class=txc-textbox&gt;[pungjoo@yeonwoo /work/home/pungjoo]$ &lt;FONT color=#5fb636&gt;&lt;FONT size=+0&gt;&lt;SPAN style=&quot;FONT-SIZE: 9pt&quot;&gt;telnet dev.pungjoo.com 80&lt;/SPAN&gt;&lt;/FONT&gt;&lt;br /&gt;
&lt;/FONT&gt;Trying 121.124.124.74...&lt;br /&gt;
Connected to dev.pungjoo.com.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
&lt;FONT color=#5fb636&gt;GET /normal HTTP/1.1&lt;br /&gt;
Host: dev.pungjoo.com&lt;br /&gt;
Connection: close&lt;br /&gt;
&lt;/FONT&gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Date: Mon, 09 Mar 2009 03:19:40 GMT&lt;br /&gt;
Content-Type: text/plain&lt;br /&gt;
&lt;FONT color=#e31600&gt;Content-Length: 12&lt;br /&gt;
&lt;/FONT&gt;Connection: close&lt;br /&gt;
&lt;br /&gt;&lt;FONT color=#e31600&gt;data1data2&lt;/FONT&gt;&lt;br /&gt;
Connection closed by foreign host.&lt;br /&gt;
[pungjoo@yeonwoo /work/home/pungjoo]$ &lt;br /&gt;
&lt;/DIV&gt;
&lt;P&gt;녹색으로 표기된 부분은&amp;nbsp;직접 입력을 한&amp;nbsp;부분이고 붉은 색으로 표기된 부분이 응답을 받은 내용중에&amp;nbsp;Content-Length에 의미를 두는 부분입니다.&lt;br /&gt;
&lt;br /&gt;클라이언트는 응답 헤더 중에 Content-Length를 통해 Body부분이 12byte로 이루어졌구나 판단 후 Body를 읽을때&amp;nbsp;InputStream에 12bytes만 읽으라고 정의를 하게 됩니다. 또한&amp;nbsp;서비스 제공하는 곳에서&amp;nbsp;첨부파일이 존재할 때 다운로드를 클릭하면&amp;nbsp;정확히 몇 바이트인 파일을&amp;nbsp;다운로드 한다고 기술되는 반면 어떤 서비스를 제공하는 곳에서는 '알 수 없는 ..' 이런 류를 보시게 됩니다. 이는 'Content-Length'가 응답 헤더에 있는냐 없느냐에 따라서 구별됩니다.&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
이상한 것은 길이가 12bytes이고 실제 'data1data2'는 총10bytes이므로 2byte의 오차가 생기는데 이는 눈에 보이지 않는 개행문자로 '\r\n'을 의미하게 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
2. Transfer-Encoding: chunked&lt;br /&gt;
&lt;br /&gt;초창기와 비교해 보면 요즘은 정적인 콘텐츠는 거의 없는 실정입니다. 비단 이미지 같은 바이너리도 동적으로 구성되어 제공되는 것이 현실입니다.&amp;nbsp;서버측에서 서비스 단위로 끊어서 로직을 진행하다 보니 모든 작업이 종료될 때까지 클라이언트는 멍하니 '흰 색'으로 채워진 내용을 보다 순간 '짠..'하고 화면에 나타나는 경우가 있게 됩니다. 이런 부분은 여러가지 요소의 영향으로 발생하는 현상이지만 순수히 Text인 Body(html)의 경우도 심심치 않게 발생하게 됩니다. 따라서 처리된 부분까지라도 그때 그때 클라이언트에 전송해 주면&amp;nbsp;클라이언트 입장에서 답답함은 조금 사라질 수 있을 것 입니다. (단, 처리되는 순서가 중요할 수 있습니다. )&lt;/P&gt;
&lt;DIV style=&quot;BORDER-BOTTOM: #c1c1c1 1px dashed; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-TOP: 10px&quot; class=txc-textbox&gt;[pungjoo@yeonwoo] $ cat Chunked.java&lt;br /&gt;
&lt;br /&gt;protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IOException {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;PrintWriter out = response.getWriter();&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.print(&quot;data1&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.flush(); &lt;FONT color=#3058d2&gt;// /normal servlet과 다르게 추가된 부분.&lt;br /&gt;
&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.print(&quot;data2&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.println();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.flush(); &lt;FONT color=#3058d2&gt;// /normal servlet과 다르게 추가된 부분.&lt;br /&gt;
&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} finally {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (out != null) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; out.close();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (Exception e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;[pungjoo@yeonwoo] $&lt;/DIV&gt;&lt;br /&gt;
위와 같은 /chunked servlet을 호출해 보겠습니다. /normal servlet과의 차이는 out.flush(); 입니다.&lt;br /&gt;
&lt;br /&gt;
&lt;DIV style=&quot;BORDER-BOTTOM: #c1c1c1 1px dashed; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #eeeeee; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-TOP: 10px&quot; class=txc-textbox&gt;[pungjoo@yeonwoo /work/home/pungjoo]$ &lt;FONT color=#5fb636&gt;telnet &lt;/FONT&gt;&lt;FONT color=#5fb636&gt;dev.pungjoo.com 80&lt;br /&gt;
&lt;/FONT&gt;Trying 121.124.124.74...&lt;br /&gt;
Connected to dev.pungjoo.com.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
&lt;FONT color=#5fb636&gt;GET /chunked HTTP/1.1&lt;br /&gt;
Host: dev.pungjoo.com&lt;br /&gt;
Connection: close&lt;br /&gt;
&lt;/FONT&gt;&lt;br /&gt;
HTTP/1.1 200 OK&lt;br /&gt;
Date: Mon, 09 Mar 2009 05:47:21 GMT&lt;br /&gt;
Connection: close&lt;br /&gt;
&lt;FONT color=#e31600&gt;Transfer-Encoding: chunked&lt;/FONT&gt;&lt;br /&gt;
Content-Type: text/plain&lt;br /&gt;
&lt;br /&gt;&lt;FONT color=#e31600&gt;5&lt;br /&gt;
data1&lt;br /&gt;
7&lt;br /&gt;
data2&lt;br /&gt;
&lt;br /&gt;0&lt;br /&gt;
&lt;/FONT&gt;&lt;br /&gt;
Connection closed by foreign host.&lt;br /&gt;
[pungjoo@yeonwoo /work/home/pungjoo]$ &lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
붉은 색으로 표기된 'Transfer-Encoding: chunked' 부분이 헤더에 추가되어 전송이 되면 클라이언트는 처음에 '5'를 읽고 '아..5 bytes. 전송하겠구나'라고&amp;nbsp;판단&amp;nbsp;5바이트를 읽고&amp;nbsp;대기(?)를 하다 '7'을 읽고 '5'와 동일하게 처리하는 것을 반복하다 '0'이 오면 더 이상 전송 받을 것이 없다고 판단하고 스트림 읽기를 중단합니다.&lt;br /&gt;
&lt;br /&gt;그런데 중요한 것이 web application server는 대체적으로&amp;nbsp;output-stream에 buffer를 둡니다. 따라서 flush를 한다고 해서 바로 클라이언트로 데이터가 전송되는 것이 아니라 buffer가 정의된 만큼 가득 차거나 더이상 전송할 것이 없을 경우 클라이언트에 데이터가 전송되므로 실질적인 앞서 설명된 효과를 얻기는 어렵습니다.&lt;br /&gt;
&lt;br /&gt;단, jsp/servlet에서 통상적으로 output을 response.getWriter()를 사용하기 때문에 설명된 것 처럼 작동(?)하지 않는 것이지 response.getOutputStream()를 사용하면 설명된 효과를 얻게 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
@</description>
      <category>HTTP</category>
      <category>chunked</category>
      <category>Content-Length</category>
      <category>http/1.1</category>
      <category>Transfer-Encoding</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/14</guid>
      <comments>https://b.pungjoo.com/entry/Transfer-Encoding-chunked-VS-Content-Length#entry14comment</comments>
      <pubDate>Mon, 9 Mar 2009 09:42:07 +0900</pubDate>
    </item>
    <item>
      <title>Cookie, Session 그대의 의미는..</title>
      <link>https://b.pungjoo.com/entry/Cookie-Session-%EA%B7%B8%EB%8C%80%EC%9D%98-%EC%9D%98%EB%AF%B8%EB%8A%94</link>
      <description>&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;U&gt;&lt;STRONG&gt;0. 들어 가면서&lt;/STRONG&gt;&lt;/U&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;br /&gt;http는 비연결 지향적인 protocol인 관계로 client와 server가 서로를 인지할 수 없는 구조입니다. 이런&amp;nbsp;비연결 상태에서 client와 server간에 &quot;너가 너냐&quot;라는 것을 알수 있게 다음과 같은 방법이 생겼습니다.&lt;br /&gt;
&lt;br /&gt;
&lt;LI&gt;parameter로 항상 들고 다니기&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 예) http:// localhost/view.jsp?id=pungjoo 
&lt;LI&gt;cookie를 설정해 항상 들고 다니기&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 예) set-cookie: id=pungjoo / cookie: id=pungjoo; 
&lt;LI&gt;사용자 정보는 server에 저장하고 client에는 cookie하나만 들고 다니기&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;예) set-cookie: JSESSIONID=GI4DEMBYGU2DAMRQ; &lt;/LI&gt;
&lt;P&gt;설명드리려 하는 부분은 2~3번에 해당 하는 항목이며, 이는 Web 보안이라는 화두속에서는 항상 언급되는 사항입니다.&lt;br /&gt;
위 2~3번 항목을 통해서 login 정보를 취득해 비정상적으로 login을 시켜 보고 이런 문제점을 보완하는 방법을 알아 보겠습니다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;U&gt;&lt;STRONG&gt;1. Request의 header/body&lt;/STRONG&gt;&lt;/U&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;br /&gt;web browser의 주소창에 url을 입력하거나 link를 click시에 server로 전송되는 내용을 request라고 합니다. 또한&amp;nbsp;request를 약간 세부적으로 분리해 보면, request는 header와 body로 나뉘어지는데 header는 target이 되는 server에&amp;nbsp;요청하고자하는&amp;nbsp;location 등등이 들어가며 body에는 form tag의 method가 post의 경우일때 입력된 값을 담게 됩니다. &lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;예를&amp;nbsp;들어 보겠습니다. http:// siyeon/view.jsp?id=pungjoo 일 경우 아래와 같이 세부적으로 보내지게됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/1230A71349AE6FEAEC&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F1230A71349AE6FEAEC&quot; width=&quot;303&quot; height=&quot;201&quot; alt=&quot;&quot; filename=&quot;get-header.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;우선 붉은 색으로 표기된 부분만 생각해 보면 &lt;br /&gt;
&lt;br /&gt;
&lt;LI&gt;server요청 방식은?&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; GET &lt;/LI&gt;
&lt;LI&gt;보고 싶은 page(URL)은?&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;http:// siyeon.com/view.jsp?id=pungjoo &amp;lt;--&amp;nbsp;녹색 처럼 요청될 수도 있습니다. 즉 /view.jsp?id=pungjoo &lt;/LI&gt;
&lt;LI&gt;난 어떤 protocol인가? &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTP/1.1 &lt;/LI&gt;
&lt;LI&gt;server는? &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Host : siyeon.com &lt;br /&gt;
&lt;/LI&gt;
&lt;P&gt;위와 같이 web browser에서 header를 만들어 siyeon.com server의&amp;nbsp;80port에 값을 전달하게됩니다. 그럼 이제 form tag의 POST method로 보낼 경우는 어떻게 세부적으로 보내는지&amp;nbsp;보겠습니다. &lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/1306521049AE700BE8&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F1306521049AE700BE8&quot; width=&quot;401&quot; height=&quot;200&quot; alt=&quot;&quot; filename=&quot;post-header-body.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
GET방식하고 비슷하나 차이가 2개가 나타납니다.&lt;br /&gt;
&lt;br /&gt;&lt;/P&gt;
&lt;OL style=&quot;LIST-STYLE-TYPE: decimal&quot;&gt;
&lt;LI&gt;GET /view.jsp?id=pungjoo 부분이 POST /view.jsp 로 parameter가 없고 &lt;/LI&gt;
&lt;LI&gt;하단에 body영역이라는 부분에 id=pungjoo 즉, parameter로 구분되어 보내지게됩니다. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;br /&gt;
여기서 주목해야할 사항이 있습니다. ( 본 글은 protocol을 설명하는 글이 아니므로 깊은 내용은 향후에 작성해 올리 겠습니다. )&lt;br /&gt;
&lt;br /&gt;&lt;/P&gt;
&lt;OL style=&quot;LIST-STYLE-TYPE: decimal&quot;&gt;
&lt;LI&gt;get 방식으로 값을 전달할 때는 길이의 제한이 있더라.. &lt;br /&gt;
경험상으로 첨부file을 보낼 때는 우리네들은 get가 아닌 post로 그래서 보내지요 
&lt;LI&gt;get 방식으로 보낼 때 한글이 깨지는데 POST로 보내면 한글이 깨지지 않더라 &lt;/LI&gt;&lt;/OL&gt;&lt;br /&gt;
&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;U&gt;&lt;STRONG&gt;&lt;br /&gt;
2. Response의 header/body&lt;/STRONG&gt;&lt;/U&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;P&gt;request가 server에 도착해서 어떤 가공이되어 client로 보내질 내용을 response라고 하는데 이 response도 header/body로 분리되어 전송되게 됩니다. header에는 일반적으로 statue code, set-cookie 등등의 정보가 기술되고 body부분에는 우리가 눈으로 자주 접하는 html code가 전송되게 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/141AE21149AE71051A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F141AE21149AE71051A&quot; width=&quot;429&quot; height=&quot;234&quot; alt=&quot;&quot; filename=&quot;Response.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
위 내용은 아래와 같이 browser에서 표기됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/140B811249AE7118AD&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F140B811249AE7118AD&quot; width=&quot;337&quot; height=&quot;174&quot; alt=&quot;&quot; filename=&quot;Response_result.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;STRONG&gt;&lt;br /&gt;
3. Request/ Response에서의 cookie&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;br /&gt;
cookie를 생성하는 곳은 client에서도 가능하고 server에서도 가능합니다. client에서 cookie를 생성하게 될 경우는 별도의 server와 생성을 위한 교류는 필요하지 않지만 server단에서 cookie를 생성하게 되면 아래 푸른색으로 표기된것과 같이 Set-Cookie라는 정보를 header를 통해서 client에 전송하게 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/13719B1449AE71D091&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F13719B1449AE71D091&quot; width=&quot;429&quot; height=&quot;234&quot; alt=&quot;&quot; filename=&quot;Response.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
즉, client는 response에 Set-Cookie라는 부분이 있으면 browser에 cookie 정보를 설정합니다. &lt;br /&gt;
&lt;BR clear=all&gt;반대로&amp;nbsp;client에서 갖고 있는 cookie는 server로 어떻게 전송되는지 보겠습니다.&lt;br /&gt;
&lt;br /&gt;Response에서 Set-Cookie: JSESSIONID=05E3694A27BF433163FE3BF45472A2E6를 보내고 browser는&amp;nbsp;특별한 경우가 아니라면 아래 푸른색 처럼 사용자가 원하지 않더라도 browser는 강제로 매번 server에 전송할 header에&amp;nbsp;넣어서 보내게 됩니다. 매번..&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/120C7B1249AE7274E4&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F120C7B1249AE7274E4&quot; width=&quot;689&quot; height=&quot;270&quot; alt=&quot;&quot; filename=&quot;cookie.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;4. WAS에서의 session &amp;amp; cookie&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;
was는 client(browser)가 접근하면 was에서 발행하는 cookie key를 찾고 key가 없으면 가급적&amp;nbsp;강제로 cookie를 하나 생성합니다. 일반적으로 그 key의 name은 JSESSIONID(java계열)로 칭하게되나 name은 임의 변경이 가능합니다.&amp;nbsp;발행한 cookie와 was에서 관리하는 session과 mapping을 합니다.( 이 부분은 was engine이 알아서 하는 부분입니다. )&lt;br /&gt;
&lt;br /&gt;이렇게 하므로 code에서 session 객체에 정보를 담았을 경우 다음번 request에 대해서 동일한 client라고 인지하고 적법한 session 객체에 접근 할수 있도록 유도해 줍니다.&lt;/P&gt;
&lt;P&gt;흐름을 그려 보면 아래와 같습니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/1530061349AE72E3E8&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F1530061349AE72E3E8&quot; width=&quot;622&quot; height=&quot;367&quot; alt=&quot;&quot; filename=&quot;sessionmaps.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;/P&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;5. 정리&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;
&lt;br /&gt;어쩌구 저쩌구.. 진행중..</description>
      <category>HTTP</category>
      <category>cookie</category>
      <category>http</category>
      <category>Session</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/13</guid>
      <comments>https://b.pungjoo.com/entry/Cookie-Session-%EA%B7%B8%EB%8C%80%EC%9D%98-%EC%9D%98%EB%AF%B8%EB%8A%94#entry13comment</comments>
      <pubDate>Wed, 4 Mar 2009 21:24:57 +0900</pubDate>
    </item>
    <item>
      <title>Object.clone()</title>
      <link>https://b.pungjoo.com/entry/Objectclone</link>
      <description>&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;&lt;SPAN style=&quot;FONT-FAMILY: Gulim&quot;&gt;&lt;SPAN style=&quot;FONT-FAMILY: Dotum&quot;&gt;들어가면서&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;br /&gt;
Clone이란 무엇일까요?&lt;br /&gt;

&lt;BLOCKQUOTE&gt;단일세포 또는 개체로부터 무성적인 증식에 의하여 생긴 유전적으로 동일한 세포군 또는 개체군을 말한다.&lt;/BLOCKQUOTE&gt;중요합니다. 유전적.. 뜻은 명확히 모르겠지만 어떤 형태적인 느낌이 듭니다..&lt;br /&gt;
&lt;br /&gt;Java에서 clone(복제)이 의미하는 것은 무엇일까요?&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-FAMILY: Dotum&quot;&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;Copy Vs Clone(Shadow Copy)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;/STRONG&gt;이런 저런 정보(객체/field)를 소유하고 있는 객체를 어느 시점에 세포 분열(clone)을 통해서 2개의 객체로 만들어 서로 다른 길을 걷게 할때 clone을 일반적으로 사용하려고들 합니다. 이때 조건은 2개로 분열된 객체가 소유하고 있는 정보(객체)에 대한 변경을 가했을때 다른 한 객체에게 영향을 주지 않아야 합니다. 만약 영향을 받을 것이라면 애초에 복제 할 필요가 없겠지요. &lt;SPAN style=&quot;FONT-SIZE: 8pt&quot;&gt;(그러나 그런 상황이 필요할 때도 있긴 합니다. 어찌 보면 더욱 의미 있을 수 있습니다.)&lt;/SPAN&gt;&lt;br /&gt;
&lt;br /&gt;복제란?..&lt;br /&gt;
만약 100Kg이 나가는&amp;nbsp;소를 복제한다고 가정하면 제가 이런 쪽은 전혀 모르겠지만, 복제하려하는 소의 유전적 형질을 이용해 새끼 소를 복제하고 이렇게 복제한 것을 유전적 형질이 동일한 복제 소라고 할 겁니다. 이때(복제가 되자 마자)&amp;nbsp;복제하기 위해 유전 형질을 제공한 소와 제공을 받은 소는 무게가 100Kg이 아니겠지요.&amp;nbsp; 즉, 복제라 함은 유전적 형질이 동일하다는 것을 의미하지 외형적으로&amp;nbsp;동일하다는 의미는 아니라는 것 입니다.&lt;br /&gt;
&lt;br /&gt;복사란?&lt;br /&gt;
A4 종이에 쓰여 있는 내용을 복사한다고 가정하면(복사기는 없다고 가정하고)&amp;nbsp;&amp;nbsp;복사하려고 하는 것과 최대한 비슷한 A4 종이, 펜, 필체 등등을&amp;nbsp;통해 쓰여진 내용을 모사하겠지요. 이처럼 복사는 원본에서 어떤한 것을 추출해서 이용하는 것은 아닌 개념입니다.&lt;br /&gt;
&lt;br /&gt;위에서 범위를 축소해 설명한 복제와 복사의 의미처럼 copy와 clone은 사실상 다른 사상입니다.&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;&lt;SPAN style=&quot;FONT-FAMILY: Dotum&quot;&gt;Object.clone()&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;br /&gt;
java에서 모든 객체의 조상(?)은 Object라고 합니다. 즉, Object를 상속 받는 다는 것 입니다. 그중에 우리가 관심을 갖는 부분은 clone()이라는 method입니다. sun의 api를 보면 Object.clone() method는&lt;br /&gt;

&lt;BLOCKQUOTE&gt;&amp;nbsp;protected native Object clone() throws CloneNotSupportedException;&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
위와 같이 되어 있습니다. native이군요. 그럼 이 native 부분을&amp;nbsp;한번 보겠습니다. java가 아니라서 머리가 아프겠지만 그냥 그런가 보다 하고 보면..&lt;br /&gt;

&lt;BLOCKQUOTE&gt;Object.c&lt;br /&gt;
&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;&lt;br /&gt;
#include &amp;lt;limits.h&amp;gt; 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;#include &quot;jni.h&quot;&lt;br /&gt;
#include &quot;jni_util.h&quot;&lt;br /&gt;
#include &quot;jvm.h&quot;&lt;/P&gt;
&lt;P&gt;#include &quot;java_lang_Object.h&quot;&lt;/P&gt;
&lt;P&gt;static JNINativeMethod methods[] = {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&quot;hashCode&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;()I&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void *)&amp;amp;JVM_IHashCode},&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&quot;wait&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;(J)V&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void *)&amp;amp;JVM_MonitorWait},&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&quot;notify&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;()V&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void *)&amp;amp;JVM_MonitorNotify},&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&quot;notifyAll&quot;,&amp;nbsp;&amp;nbsp; &quot;()V&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (void *)&amp;amp;JVM_MonitorNotifyAll},&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#3058d2&gt; {&quot;clone&quot;,&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &quot;()Ljava/lang/Object;&quot;,&amp;nbsp;&amp;nbsp; (void *)&amp;amp;JVM_Clone},&lt;br /&gt;
&lt;/FONT&gt;};&lt;/P&gt;
&lt;P&gt;JNIEXPORT void JNICALL&lt;br /&gt;
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; (*env)-&amp;gt;RegisterNatives(env, cls,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; methods, sizeof(methods)/sizeof(methods[0]));&lt;br /&gt;
}&lt;/P&gt;
&lt;P&gt;JNIEXPORT jclass JNICALL&lt;br /&gt;
Java_java_lang_Object_getClass(JNIEnv *env, jobject this)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (this == NULL) {&lt;br /&gt;
&amp;nbsp;JNU_ThrowNullPointerException(env, NULL);&lt;br /&gt;
&amp;nbsp;return 0;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;
&amp;nbsp;return (*env)-&amp;gt;GetObjectClass(env, this);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
&lt;br /&gt;실제 구현되는 부분을 보면..&lt;br /&gt;

&lt;BLOCKQUOTE&gt;jvm.cpp&lt;br /&gt;
&lt;br /&gt;JVM_ENTRY(jobject, &lt;FONT color=#3058d2&gt;JVM_Clone(JNIEnv* env, jobject handle)&lt;/FONT&gt;)&lt;br /&gt;
&amp;nbsp; JVMWrapper(&quot;JVM_Clone&quot;);&lt;br /&gt;
&amp;nbsp; Handle obj(THREAD, JNIHandles::resolve_non_null(handle));&lt;br /&gt;
&amp;nbsp; const KlassHandle klass (THREAD, obj-&amp;gt;klass());&lt;br /&gt;
&amp;nbsp; JvmtiVMObjectAllocEventCollector oam; 
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;#ifdef ASSERT&lt;br /&gt;
&amp;nbsp; // Just checking that the cloneable flag is set correct&lt;br /&gt;
&amp;nbsp; if (obj-&amp;gt;is_array()) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; guarantee(klass-&amp;gt;is_cloneable(), &quot;all arrays are cloneable&quot;);&lt;br /&gt;
&amp;nbsp; } else {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; guarantee(obj-&amp;gt;is_instance(), &quot;should be instanceOop&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; bool cloneable = klass-&amp;gt;is_subtype_of(SystemDictionary::cloneable_klass());&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; guarantee(cloneable == klass-&amp;gt;is_cloneable(), &quot;incorrect cloneable flag&quot;);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
#endif&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#e31600&gt;&amp;nbsp; // Check if class of obj supports the Cloneable interface.&lt;br /&gt;
&amp;nbsp; // All arrays are considered to be cloneable (See JLS 20.1.5)&lt;br /&gt;
&amp;nbsp; if (!klass-&amp;gt;is_cloneable()) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ResourceMark rm(THREAD);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass-&amp;gt;external_name());&lt;br /&gt;
&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp; // Make shallow object copy&lt;br /&gt;
&amp;nbsp; const int size = obj-&amp;gt;size();&lt;br /&gt;
&amp;nbsp; oop new_obj = NULL;&lt;br /&gt;
&amp;nbsp; if (obj-&amp;gt;is_array()) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; const int length = ((arrayOop)obj())-&amp;gt;length();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);&lt;br /&gt;
&amp;nbsp; } else {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; // 4839641 (4840070): We must do an oop-atomic copy, because if another thread&lt;br /&gt;
&amp;nbsp; // is modifying a reference field in the clonee, a non-oop-atomic copy might&lt;br /&gt;
&amp;nbsp; // be suspended in the middle of copying the pointer and end up with parts&lt;br /&gt;
&amp;nbsp; // of two different pointers in the field.&amp;nbsp; Subsequent dereferences will crash.&lt;br /&gt;
&amp;nbsp; // 4846409: an oop-copy of objects with long or double fields or arrays of same&lt;br /&gt;
&amp;nbsp; // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead&lt;br /&gt;
&amp;nbsp; // of oops.&amp;nbsp; We know objects are aligned on a minimum of an jlong boundary.&lt;br /&gt;
&amp;nbsp; assert(MinObjAlignmentInBytes &amp;gt;= BytesPerLong, &quot;objects misaligned&quot;);&lt;br /&gt;
&amp;nbsp; Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (size_t)align_object_size(size) / HeapWordsPerLong);&lt;br /&gt;
&amp;nbsp; // Clear the header&lt;br /&gt;
&amp;nbsp; new_obj-&amp;gt;init_mark();&lt;/P&gt;
&lt;P&gt;&amp;nbsp; // Store check (mark entire object and let gc sort it out)&lt;br /&gt;
&amp;nbsp; BarrierSet* bs = Universe::heap()-&amp;gt;barrier_set();&lt;br /&gt;
&amp;nbsp; assert(bs-&amp;gt;has_write_region_opt(), &quot;Barrier set does not have write_region&quot;);&lt;br /&gt;
&amp;nbsp; bs-&amp;gt;write_region(MemRegion((HeapWord*)new_obj, size));&lt;/P&gt;
&lt;P&gt;&amp;nbsp; // Caution: this involves a java upcall, so the clone should be&lt;br /&gt;
&amp;nbsp; // &quot;gc-robust&quot; by this stage.&lt;br /&gt;
&amp;nbsp; if (klass-&amp;gt;has_finalizer()) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; assert(obj-&amp;gt;is_instance(), &quot;should be instanceOop&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new_obj = instanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL);&lt;br /&gt;
&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp; return JNIHandles::make_local(env, oop(new_obj));&lt;br /&gt;
JVM_END&amp;nbsp;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;처럼되어 있습니다. 그냥 복잡합니다.. ^^;&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;그럼 어떻게 사용하나?&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;br /&gt;
모든 객체는 Object를 묵시적으로 상속 받기 때문에 다음과 같이 합니다. 
&lt;BLOCKQUOTE&gt;package com.pungjoo.edu.clone; 
&lt;P&gt;public class SomeThingClass {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;main(String[] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;SomeThingClass clazz = new SomeThingClass();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;SomeThingClass cloneClazz = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz = (SomeThingClass) &lt;FONT color=#e31600&gt;clazz.clone();&lt;br /&gt;
&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;} catch (CloneNotSupportedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;e.printStackTrace();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;그러나 실행해 보면 아래와 같이 CloneNotSupportedException이 발생합니다. 
&lt;BLOCKQUOTE&gt;java.lang.CloneNotSupportedException: com.pungjoo.edu.clone.SomeThingClass&lt;br /&gt;
&amp;nbsp;at java.lang.Object.clone(Native Method)&lt;br /&gt;
&amp;nbsp;at com.pungjoo.edu.clone.SomeThingClass.main(SomeThingClass.java:9)&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
왜 그럴까요? 이는&lt;STRONG&gt; jvm.cpp의 붉은색 block&lt;/STRONG&gt;에서 현재 class가 &lt;FONT color=#3058d2&gt;&lt;FONT color=#000000&gt;'&lt;/FONT&gt;&lt;STRONG&gt;Cloneable interface&lt;/STRONG&gt;&lt;/FONT&gt;'를 implement 했는지 확인하기 때문에 그렇습니다.&amp;nbsp;&lt;br /&gt;

&lt;BLOCKQUOTE&gt;&lt;FONT color=#e31600&gt;&amp;nbsp; // Check if class of obj supports the Cloneable interface.&lt;br /&gt;
&amp;nbsp; // All arrays are considered to be cloneable (See JLS 20.1.5)&lt;br /&gt;
&amp;nbsp; if (!klass-&amp;gt;is_cloneable()) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ResourceMark rm(THREAD);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass-&amp;gt;external_name());&lt;br /&gt;
&amp;nbsp; }&lt;/FONT&gt;&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
따라서 올바르게 사용하려면 다음과 같이해야 합니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;
&lt;P&gt;package com.pungjoo.edu.clone;&lt;/P&gt;
&lt;P&gt;public class SomeThingClass &lt;FONT color=#5c7fb0&gt;&lt;STRONG&gt;implements Cloneable&lt;/STRONG&gt; &lt;/FONT&gt;{&lt;/P&gt;
&lt;P&gt;&amp;nbsp;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;main(String[] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;SomeThingClass clazz = new SomeThingClass();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;SomeThingClass cloneClazz = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz = (SomeThingClass) clazz.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;} catch (CloneNotSupportedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;e.printStackTrace();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&amp;nbsp;}&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;br /&gt;
생각 보다는 간단하게 사용할 수 있습니다. 그러나 이후부터 혼란의 세계에 빠져들기 시작합니다.&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;혼란스러워하기...&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;package com.pungjoo.edu.clone; 
&lt;P&gt;import java.util.Set;&lt;br /&gt;
import java.util.TreeSet;&lt;/P&gt;
&lt;P&gt;public class Animal implements Cloneable {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Set&amp;lt;String&amp;gt; animals;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Animal() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals = new TreeSet&amp;lt;String&amp;gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void init() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;lion&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;tortoise&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;bee&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void print() {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(animals);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal clazz = new Animal();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;FONT color=#3058d2&gt; &lt;STRONG&gt;clazz.init(); //--&amp;gt; A&lt;br /&gt;
&lt;/STRONG&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal cloneClazz = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cloneClazz = (SomeThingClass) clazz.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#3058d2&gt;&lt;STRONG&gt;// clazz.init(); //--&amp;gt; B&lt;br /&gt;
&lt;/STRONG&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printAll(clazz, cloneClazz);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (CloneNotSupportedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void printAll(Animal clazz, Animal cloneClazz) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;원본 &quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.print();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;복제 &quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz.print();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;위&amp;nbsp; 결과는 아래와 같습니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;원본 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 벌, 사자]&lt;/BLOCKQUOTE&gt;그럼 파란색으로 되어 있는 'A'라인을&amp;nbsp;주석처리하고 주석처리되어 있는 'B'라인의&amp;nbsp;주석을 제거하고 실행하면 어떻게 될까요?&lt;br /&gt;
결과는 동일하게 나옵니다. 왜 그럴까요? 이제부터 혼란스럽기 시작합니다.&lt;br /&gt;
&lt;br /&gt;논리적으로 &lt;STRONG&gt;cloneClazz = (Animal) clazz.clone();&lt;/STRONG&gt;를 하는 시점에&amp;nbsp;clazz.init()가 호출되지 않았기 때문에 cloneClazz는&amp;nbsp;null또는 []으로&amp;nbsp;나와야겠지요. 그러나 clone()이라는 것은 복제하려고 하는 원본에 설정된 '레퍼런스'를 복제하는&amp;nbsp;개념이기 때문에 animals 객체에 무엇이 들어 있는지는 중요하지 않습니다. &amp;nbsp;중요한 것은 animals 객체가 바라보고 있는 레퍼런스가 중요하고 결론적으로 원본의 animals 객체가 바라 보는 레퍼런스를 복제된 animals 객체도 바라 보게 됩니다.&amp;nbsp;따라서 복제된 후에 원본의 clazz.init()를 통해서 add되었다 하더라도 cloneclazz의 animals 객체는 원본의 animals 객체와 동일한 레퍼런스를 바라 보기 때문에 동일한 결과가 나오게 됩니다.&amp;nbsp; (&amp;nbsp;단, Animal 생성자에서 animals를 설정하지 않으면 생각했던 결과가 나옵니다.&amp;nbsp;)&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs15/12_tistory_2008_12_15_18_15_4946201e3cc2b?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs15%2F12_tistory_2008_12_15_18_15_4946201e3cc2b%3Foriginal&quot; width=&quot;639&quot; height=&quot;300&quot; alt=&quot;&quot; filename=&quot;clone.png&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
위와 동일한 효과가 발생하는 다른 예를 한번 보겠습니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;package com.pungjoo.edu.clone; 
&lt;P&gt;import java.util.Set;&lt;br /&gt;
import java.util.TreeSet;&lt;/P&gt;
&lt;P&gt;public class Animal implements Cloneable {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Set&amp;lt;String&amp;gt; animals;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Animal() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals = new TreeSet&amp;lt;String&amp;gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void init() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;사자&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;거북이&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;벌&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void remove() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.remove(&quot;거북이&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void print() {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(animals);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal clazz = new Animal();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.init();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal cloneClazz = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz = (Animal) clazz.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printAll(clazz, cloneClazz);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;FONT color=#e31600&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println( &quot;원본에서 거북이를 삭제함.&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.remove();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printAll(clazz, cloneClazz);&lt;br /&gt;
&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (CloneNotSupportedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void printAll(Animal clazz, Animal cloneClazz) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;원본 &quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.print();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;복제 &quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz.print();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;결과는 다음과 같습니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;원본 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
복제 &lt;br /&gt;
&lt;br /&gt;[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;원본에서 거북이를 삭제함.&lt;br /&gt;
원본 &lt;br /&gt;
&lt;FONT color=#e31600&gt;[벌, 사자]&lt;br /&gt;
&lt;/FONT&gt;&lt;br /&gt;
복제 &lt;br /&gt;
&lt;FONT color=#e31600&gt;[벌, 사자]&lt;/FONT&gt;&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
원본(clazz)에서 삭제했으면&amp;nbsp;복제(cloneclazz) 객체도 적용되게 됩니다.&lt;br /&gt;
&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;&lt;br /&gt;
본래&amp;nbsp;의도하는 복제(복사) 객체 만들기&lt;br /&gt;
&lt;/SPAN&gt;&lt;/STRONG&gt;이런 저런 책을 보면 위와 같이 '레퍼런스'를 동일하게 갖게 되기때문에 clone() method를 override하라고 되어 있습니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;&lt;FONT color=#5c7fb0&gt;&lt;EM&gt;@Override&lt;br /&gt;
public&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clone() throws CloneNotSupportedException{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal retObj = (Animal) super.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return retObj;&lt;br /&gt;
}&lt;/EM&gt;&lt;/FONT&gt;&lt;/BLOCKQUOTE&gt;그러나 위와 같이 override를 한다고 해서 본질이 해결되지는 않습니다. 이유는 override를 하지 않든 위와 같이 하든 결론은 본질적인 부분에 대한 추가가 없기&amp;nbsp;때문에 그렇습니다.&amp;nbsp; 그럼 어떻게 해야 하나?.. 결론은 &lt;STRONG&gt;&lt;U&gt;Set&amp;lt;String&amp;gt; animals &lt;/U&gt;&lt;/STRONG&gt;객체를 복제(복사)를 해 줘야 합니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;@Override&lt;br /&gt;
public&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clone() throws CloneNotSupportedException{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal retObj = (Animal) super.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#5c7fb0&gt;&lt;STRONG&gt;retObj.animals = (Set&amp;lt;String&amp;gt;) ((TreeSet&amp;lt;String&amp;gt;) this.animals).clone();&lt;br /&gt;
&lt;/STRONG&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return retObj;&lt;br /&gt;
}&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
위와 같이 override하고 animals 객체에 add하는 method를 추가하고 cloneclazz에서 호출해 봅시다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;package com.pungjoo.edu.clone; 
&lt;P&gt;import java.util.Set;&lt;br /&gt;
import java.util.TreeSet;&lt;/P&gt;
&lt;P&gt;public class Animal implements Cloneable {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Set&amp;lt;String&amp;gt; animals;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Animal() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals = new TreeSet&amp;lt;String&amp;gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#5c7fb0&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Override&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clone() throws CloneNotSupportedException{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal retObj = (Animal) super.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retObj.animals = (Set&amp;lt;String&amp;gt;) ((TreeSet&amp;lt;String&amp;gt;) this.animals).clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return retObj;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;/FONT&gt;&lt;/STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void init() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;사자&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;거북이&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;벌&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#5c7fb0&gt;&lt;STRONG&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; void&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; add() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.add(&quot;낙타&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;/STRONG&gt;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void remove() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals.remove(&quot;거북이&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void print() {&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(animals);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal clazz = new Animal();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.init();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal cloneClazz = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz = (Animal) clazz.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printAll(clazz, cloneClazz);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println( &quot;원본에서 거북이를 삭제함.&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.remove();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;STRONG&gt;&lt;FONT color=#5c7fb0&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println( &quot;복제에 낙타를 추가함&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz.add();&lt;/FONT&gt;&lt;/STRONG&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printAll(clazz, cloneClazz);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (CloneNotSupportedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void printAll(Animal clazz, Animal cloneClazz) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;원본 &quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clazz.print();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;복제 &quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cloneClazz.print();&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
&lt;br /&gt;결과를 한번 볼까요?&lt;br /&gt;

&lt;BLOCKQUOTE&gt;원본&lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;원본에서 거북이를 삭제함.&lt;br /&gt;
복제에 낙타를 추가함&lt;br /&gt;
&lt;STRONG&gt;&lt;FONT color=#5c7fb0&gt;원본 &lt;br /&gt;
[벌, 사자]&lt;/FONT&gt;&lt;/STRONG&gt;&lt;br /&gt;
&lt;br /&gt;&lt;FONT color=#5c7fb0&gt;&lt;STRONG&gt;복제 &lt;br /&gt;
[거북이, 낙타, 벌, 사자]&lt;/STRONG&gt;&lt;/FONT&gt;&lt;br /&gt;
&lt;br /&gt;&lt;/BLOCKQUOTE&gt;이제 의도하는 형태로 복제(복사)가 되었습니다.&lt;br /&gt;
&lt;br /&gt;참고로 TreeSet.clone() method를 보면 
&lt;BLOCKQUOTE&gt;public Object clone() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TreeSet&amp;lt;E&amp;gt; clone = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clone = (TreeSet&amp;lt;E&amp;gt;) super.clone();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (CloneNotSupportedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new InternalError();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } 
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clone.m = new TreeMap&amp;lt;E,Object&amp;gt;(m);&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return clone;&lt;br /&gt;
}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;&lt;br /&gt;
남은 의문점? clone() method를 그럼 new Object(); 하면 안되나?&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;br /&gt;
복제가 복제아닌 복사처럼 되어 버린다면 즉, clone method를 호출한 것으로 끝나지 않고 사용되는 data field를 각각 복제를 해야 한다면 다음과 같은 형태로 하면 안 될까요?&lt;br /&gt;

&lt;BLOCKQUOTE&gt;@Override&lt;br /&gt;
public&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Object&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clone() throws CloneNotSupportedException{&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Animal retObj = new Animal();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; retObj.animals = new TreeSet&amp;lt;String&amp;gt;( this.animals);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return retObj;&lt;br /&gt;
}&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;&lt;br /&gt;
위와 같이 clone() method를 수정해도 결론은 아래와 같습니다.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;원본&lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;원본에서 거북이를 삭제함.&lt;br /&gt;
복제에 낙타를 추가함&lt;br /&gt;
원본 &lt;br /&gt;
[벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 낙타, 벌, 사자]&lt;/BLOCKQUOTE&gt;차이가 없네요?&lt;br /&gt;
&lt;br /&gt;어짜피 data field를 다시 채우기 위해서 기술한다면 그냥 new Object()하고 field를 채우면 되는 것을 복잡하고 혼란스럽게 super.clone()을 할까요?&lt;br /&gt;
&lt;br /&gt;sample 소스의 생성자( public Animal(){} ) 부분에 System.out.println(...)을&amp;nbsp;추가하고 비교해 봅시다....&lt;br /&gt;

&lt;BLOCKQUOTE&gt;public Animal() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; animals = new TreeSet&amp;lt;String&amp;gt;();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;STRONG&gt;&lt;FONT color=#5c7fb0&gt; System.out.println( getClass().getName() + &quot; 을 호출 합니다.&quot;);&lt;br /&gt;
&lt;/FONT&gt;&lt;/STRONG&gt;}&lt;br /&gt;
&lt;/BLOCKQUOTE&gt;위와 같이 생성자를 변경하고 super.clone() 형태로 실행하면..&lt;br /&gt;

&lt;BLOCKQUOTE&gt;&lt;STRONG&gt;&lt;FONT color=#e31600&gt;com.pungjoo.edu.clone.Animal 을 호출 합니다.&lt;br /&gt;
&lt;/FONT&gt;&lt;/STRONG&gt;원본 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;원본에서 거북이를 삭제함.&lt;br /&gt;
복제에 낙타를 추가함&lt;br /&gt;
원본 &lt;br /&gt;
[벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 낙타, 벌, 사자] &lt;/BLOCKQUOTE&gt;&lt;br /&gt;
이번에는 new Object(); 형태로 실행하면.&lt;br /&gt;

&lt;BLOCKQUOTE&gt;&lt;STRONG&gt;&lt;FONT color=#e31600&gt;com.pungjoo.edu.clone.Animal 을 호출 합니다.&lt;br /&gt;
com.pungjoo.edu.clone.Animal 을 호출 합니다.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;br /&gt;
원본 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 벌, 사자]&lt;br /&gt;
&lt;br /&gt;원본에서 거북이를 삭제함.&lt;br /&gt;
복제에 낙타를 추가함&lt;br /&gt;
원본 &lt;br /&gt;
[벌, 사자]&lt;br /&gt;
&lt;br /&gt;복제 &lt;br /&gt;
[거북이, 낙타, 벌, 사자] &lt;/BLOCKQUOTE&gt;다르지요? super.clone() 형태일때는&amp;nbsp;생성자가 1회 ( Animal clazz = new Animal(); ) 호출되고 new Object() 형태일때는 생성자가 2회 ( Animal clazz = new Animal(); 에서 한번 Animal retObj = new Animal(); 에서 한번) 호출 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 12pt&quot;&gt;정리하면 &lt;/SPAN&gt;&lt;br /&gt;
&lt;/STRONG&gt;supe.clone()을&amp;nbsp;호출하면&amp;nbsp;생성자 호출 없이 원본의 객체를 native Level에서 복제합니다. 역시나 복제 개념상 data field가 바라 보는 레퍼런스도 동일한 곳을 바라 보도록 복제가 됩니다. 이때까지는 복제입니다. 이제 실제 우리가 의미를 두는 즉, data field는 복제 개념이 아닌 복사 개념으로 명시적으로 복제를 해 줘야 합니다. 이때 중요한 부분은 data field도 new Object() 형태로 설정하면 안됩니다. 즉, data field 객체도 clone()을 동일한 형태로 구현하고 있어야 한다는 것 입니다. 가급적말이죠. (조상에 조상까지 가면 어쩔수 없이 new Object를 하게 됩니다만..)&lt;br /&gt;
&lt;br /&gt;만약에 후자( new Object() ) 형태로 했을 때 예시에는 단순히 문자열 출력을 했으나 database를 오고 가거나 타 시스템과 연동, 또는&amp;nbsp;타 Object를 호출하거나 하는 형태가 들어 있다면 중복적인 행위가 유발되게 됩니다. 따라서 이런&amp;nbsp;부분을 피하면서 객체를 복제 하는 것이 Object.clone()의 역할입니다.&lt;br /&gt;
&lt;br /&gt;덧말 &lt;br /&gt;
간혹 Primitive Data Types 또는 String 객체로 하고 '어라 난 잘되는데'라고 생각하시겠지만,&amp;nbsp;String 객체는 String type에 대한 본래 특성상 혼란을 가중시키는 요소가 있습니다. 해당 부분을 언급하고자 했으나 글의 내용상 Object.clone()을 다루는 글이기 때문에 제외했습니다.&lt;br /&gt;
&lt;br /&gt;@</description>
      <category>JAVA</category>
      <category>clone</category>
      <category>Java</category>
      <category>object</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/11</guid>
      <comments>https://b.pungjoo.com/entry/Objectclone#entry11comment</comments>
      <pubDate>Thu, 11 Dec 2008 10:09:20 +0900</pubDate>
    </item>
    <item>
      <title>final의 용도.</title>
      <link>https://b.pungjoo.com/entry/final%EC%9D%98-%EC%9A%A9%EB%8F%84</link>
      <description>&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;STRONG&gt;들어가면서&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;br /&gt;
final의 용도는 큰 줄기에서는 '한번 정의된 레퍼런스를 변경 할 수 없다.'입니다.&lt;br /&gt;
이 final은 아래와 같이 3가지 case로 볼 수 있습니다.&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;class 확장(extend) 및&amp;nbsp;mehotd override를 제한&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #79a5e4 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #79a5e4 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #79a5e4 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #79a5e4 1px solid; BACKGROUND-COLOR: #dbe8fb&quot;&gt;package com.pungjoo.edu;&lt;br /&gt;
&lt;br /&gt;&lt;FONT color=#e31600&gt;final &lt;/FONT&gt;public class SomeClass {&lt;br /&gt;
&lt;br /&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;main(String[] args) {&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;&lt;br /&gt;
new SomeClass(){&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //-&amp;gt; A&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;};&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;&lt;/DIV&gt;
&lt;DIV&gt;}&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;br /&gt;
위와 같이 &lt;FONT color=#e31600&gt;final &lt;/FONT&gt;public( 또는 public final )으로 class를 선언하면 extend를 할 수 없게 됩니다. 즉, 해당 class에 대한&amp;nbsp;변경(?)을 허용하지 않습니다. 컴파일시에 'A' 라인에서 'cannot inherit from final com.pungjoo.edu.SomeClass' 컴파일 오류가 발생합니다.&lt;br /&gt;
&lt;br /&gt;그러나 class를 확장하는 것은 허용하지만 특정 method를 override를 하는 것을 허용하지 않을 때도 사용 할 수 있습니다.&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #79a5e4 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #79a5e4 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #79a5e4 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #79a5e4 1px solid; BACKGROUND-COLOR: #dbe8fb&quot;&gt;package com.pungjoo.edu;&lt;br /&gt;
&lt;br /&gt;public class SomeClass {&lt;br /&gt;
&lt;br /&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;public&amp;nbsp;&lt;FONT color=#e31600&gt;final&lt;/FONT&gt; void&amp;nbsp;someMethod(int para){&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;}&lt;br /&gt;
&lt;br /&gt;&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;public&amp;nbsp;static&amp;nbsp;void&amp;nbsp;main(String[] args) {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;익명 클래스&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;new SomeClass() {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 12em&quot;&gt;@Override&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 12em&quot;&gt;public&amp;nbsp;void&amp;nbsp;someMethod(int para){&amp;nbsp; // --&amp;gt; A&amp;nbsp;&amp;nbsp; &lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 16em&quot;&gt;// 변경..&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 12em&quot;&gt;}&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;};&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;}&lt;br /&gt;
&lt;br /&gt;&lt;/DIV&gt;
&lt;DIV&gt;}&lt;/DIV&gt;&lt;/DIV&gt;&lt;br /&gt;
위와 같이 본래의 someMethod에 public &lt;FONT color=#e31600&gt;final&lt;/FONT&gt;( 또는 final public )을 하면 컴파일시에 'A' 라인에서 'cannot override someMethod(int) in com.pungjoo.edu.SomeClass; overridden method is final'이라는 컴파일 오류가 발생합니다.&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;로컬변수를 inner-class에서 사용 (지역클래스)&lt;/SPAN&gt;&lt;br /&gt;
&lt;/STRONG&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #79a5e4 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #79a5e4 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #79a5e4 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #79a5e4 1px solid; BACKGROUND-COLOR: #dbe8fb&quot;&gt;&lt;br /&gt;
package com.pungjoo.edu;&lt;br /&gt;
&lt;br /&gt;public class SomeClass {&lt;br /&gt;
&lt;br /&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;public void someMethod(int x) {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;int value = x + 200;&lt;br /&gt;
&lt;br /&gt;class InnerClass {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 12em&quot;&gt;void temp() {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 16em&quot;&gt;System.out.println(value);&amp;nbsp; // -&amp;gt; A&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 12em&quot;&gt;}&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;}&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;}&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;/DIV&gt;&lt;/DIV&gt;&lt;br /&gt;
위와 같은 형태에서는 value를 inner class의 temp() method에서 참조를 기본적으로 할 수 없기 때문에 컴파일시에 'local variable value is accessed from within inner class; needs to be declared final' 컴파일 오류가 발생합니다. &lt;br /&gt;
&lt;br /&gt;이럴 경우는 'int value = x + 200;' 부분을 '&lt;FONT color=#e31600&gt;final&lt;/FONT&gt; int value = x + 200;'로 final을 추가하면 해결이 됩니다만, 주의 할 점은 value를 final로 선언 했기때문에 해당 value를 변경 할 수는 없게 됩니다. &lt;br /&gt;
&lt;br /&gt;만약 inner class block(포함)을 벗어난 곳에서 value를 변경하는 구문이 들어가면 'value = 200;' 같이 추가하고 컴파일 한다면 'cannot assign a value to final variable value'라는 컴파일 오류가 발생하게 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;U&gt;method parameter 재생성 금지&lt;/U&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;/STRONG&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #79a5e4 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #79a5e4 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #79a5e4 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #79a5e4 1px solid; BACKGROUND-COLOR: #dbe8fb&quot;&gt;package com.pungjoo.edu;&lt;br /&gt;
&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;
import java.util.Map;&lt;br /&gt;
&lt;br /&gt;public class SomeClass {&lt;br /&gt;
&lt;br /&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;public void someMethod(Map map) {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;&lt;br /&gt;
Object key = null;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;// 이런 저런 처리..&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;map.get(key);&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;// 초기화 하자..? &lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;map = new HashMap(); // -&amp;gt; A&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;public static void main(String[] args) {&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;SomeClass clazz = new SomeClass();&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;Map map = new HashMap();&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;String key = &quot;name&quot;;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;String value = &quot;pungjoo&quot;;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;map.put(key, value);&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;clazz.someMethod(map);&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 8em&quot;&gt;System.out.println(&quot;Size : &quot; + map.size());&lt;br /&gt;
&lt;/DIV&gt;
&lt;DIV style=&quot;MARGIN-LEFT: 4em&quot;&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;&lt;/DIV&gt;
&lt;DIV&gt;}&lt;br /&gt;
&lt;/DIV&gt;&lt;/DIV&gt;&lt;br /&gt;
method의 parameter로 선언된 객체를 new 생성자를 통해 new를 해 버리면 method return시에&amp;nbsp;자신이 new했기 때문에 위와 같은 경우 '0'이 찍히겠지 싶지만 그렇지 않습니다. &lt;br /&gt;
따라서 저런 실수를 원천적으로 막고 싶은 경우는 'public void someMethod(Map map)' 부분을 'public void someMethod(&lt;FONT color=#e31600&gt;final Map map&lt;/FONT&gt;)'로 선언하면 컴파일시에 ' final parameter map may not be assigned' 컴파일 오류가 나게 됩니다. &lt;br /&gt;
&lt;br /&gt;만약 정상적으로 초기화하고 싶다면 'A' 부분을 'map.clean();'라고 하는 것이 맞겠죠.&lt;br /&gt;
&lt;br /&gt;@&lt;br /&gt;</description>
      <category>JAVA</category>
      <category>Java</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/10</guid>
      <comments>https://b.pungjoo.com/entry/final%EC%9D%98-%EC%9A%A9%EB%8F%84#entry10comment</comments>
      <pubDate>Mon, 10 Nov 2008 20:42:42 +0900</pubDate>
    </item>
    <item>
      <title>get...URI()에 대한 고찰</title>
      <link>https://b.pungjoo.com/entry/getURI%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0</link>
      <description>&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;들어 가면서&lt;/span&gt;&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;
일반적으로 스프링을 쓰는 환경에서&amp;nbsp;VIEW PAGE인 JSP PAGE에서 request.getRequestURI()를 사용하면 원하는 URI를 얻지 못 합니다. 즉, 유입 URI를 돌려 주는 것이 아니라 controller에서 정의한 PAGE를 얻게 되어 결국에는 사용자가 입력한 실제 URI를 얻을 수 없게 됩니다.&lt;br /&gt;
&lt;br /&gt;
그래서 일반적으로 controller에서 getRqeustURI()한 결과를 request.setAttribute(key, value)를 통해서 Value를 설정하고 VIEW PAGE인 JSP PAGE에서 getAttribute( key )를 사용합니다..&lt;/p&gt;
&lt;p&gt;정말 얻을 수 없을까?&lt;br /&gt;
&lt;br /&gt;
자자... servlet spec을 정의하는 양반들이 바보였을까? &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;Case 명세서&lt;/span&gt;&lt;br /&gt;
&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;ul style=&quot;LIST-STYLE-TYPE: square&quot;&gt;
&lt;li&gt;springframework을 사용한다. &lt;/li&gt;
&lt;li&gt;사용자는 &lt;a href=&quot;http://some.pungjoo.com/index.pj&quot;&gt;http://some.pungjoo.com/index.pj&lt;/a&gt; 라고 URL 입력창에 입력함 &lt;/li&gt;
&lt;li&gt;해당 요청에 대한 처리 과정을 들여다 보면 controller에서 필요한 service를 호출해 request의 attribute에 저장하고 &lt;br /&gt;
최종적으로 /WEB-INF/jsp/default_index.jsp를 호출하는 구조이며 &lt;br /&gt;
최종적으로 호출을 받은 JSP PAGE에서 사용자가 호출한 URI를 기술함. &lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;알려진 문제점&lt;/span&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/u&gt;위 명세서를 구현함에 있어서 마지막 부분을 일반적으로 다음과 같이 기술하게 됩니다.&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;
String uri = request.getRequestURI();&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;그런데 위와 같이 기술하면 uri에 어떤 value가 들어 올까요?&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;
/WEB-INF/jsp/default_index.jsp&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;위와 같은 결과가 나오게 됩니다. 경험 있는 분들은 그래서 다음과 같이 합니다.&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;
request.setAttribute( &quot;URI&quot;, request.getRequestURI() );&lt;br /&gt;
&lt;br /&gt;
/WEB-INF/jsp/default_index.jsp page에서...&lt;br /&gt;
String uri = (String)request.getAttribute( &quot;URI&quot; );&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;servlet spec 정의하는 양반들은 바보가 아니었다.&lt;/span&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/u&gt;일반적으로 uri mapping을 통해서 움직이는 framework은 내부적으로 종단의 VIEW JSP로 가기 위해서 RequestDispatcher의 include(...) 또는 forward(...)를 통해서 VIEW PAGE로 보내줍니다. &lt;br /&gt;
&lt;br /&gt;
이런 상황하에서 우리네들은 request.getRequesURI()를 호출하는데 이렇게 되면 getRequestURI은 RequestDispatcher의 URI가 됩니다, 즉 부모의 URI를 돌려 주게 됩니다.&lt;/p&gt;
&lt;p&gt;이런 상황이다 보니 servlet spec에는 다음과 같은 key/value가 request attribute에 자동으로 들어가게 됩니다. 부모 PAGE에서 자식을 호출 하는 방식에 따라서&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #f3c534 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #f3c534 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #f3c534 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #f3c534 1px dashed; BACKGROUND-COLOR: #fefeb8&quot;&gt;
request.getAttribute( &quot;javax.servlet.forward.request_uri&quot; );&lt;br /&gt;
request.getAttribute( &quot;javax.servlet.include.request_uri&quot; );&lt;/div&gt;
&lt;p&gt;&lt;u&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;결론&lt;/span&gt;&lt;br /&gt;
&lt;/strong&gt;&lt;/u&gt;SpringFramework을 사용하는 우리네들은 VIEW PAGE에서 사용자가 요청한 URI를 얻고 싶으면 다음과 같이 하세요.&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;
&lt;div class=&quot;txc-textbox&quot; style=&quot;BORDER-RIGHT: #79a5e4 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #79a5e4 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #79a5e4 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #79a5e4 1px dashed; BACKGROUND-COLOR: #dbe8fb&quot;&gt;
&lt;div style=&quot;TEXT-ALIGN: center&quot;&gt;
String uri = (String)request.getAttribute( &quot;javax.servlet.forward.request_uri&quot; );&amp;nbsp; &lt;br /&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;@ &lt;br /&gt;
&lt;/p&gt;</description>
      <category>JAVA</category>
      <category>getRequestURI</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/3</guid>
      <comments>https://b.pungjoo.com/entry/getURI%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0#entry3comment</comments>
      <pubDate>Tue, 24 Jun 2008 00:37:00 +0900</pubDate>
    </item>
    <item>
      <title>Failed to invoke last-modified method - springframework</title>
      <link>https://b.pungjoo.com/entry/Failed-to-invoke-last-modified-method-springframework</link>
      <description>&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;U&gt;&lt;STRONG&gt;인지&lt;/STRONG&gt;&lt;/U&gt;&lt;/SPAN&gt;&lt;br /&gt;
Failed to invoke last-modified method 발생하며 StackOverFlow&amp;nbsp;발생.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;일반적인 해결 방안&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;@Override&lt;br /&gt;
public long getLastModified(HttpServletRequest request) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -1;&lt;br /&gt;
}&lt;/DIV&gt;&lt;br /&gt;
&lt;br /&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;STRONG&gt;&lt;U&gt;왜 그럴까?&lt;/U&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;&amp;lt;bean id=&quot;xxxMethodNameResolver&quot; class=&quot;org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver&quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property name=&quot;mappings&quot;&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;props&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;prop key=&quot;/xxx.abc&quot;&amp;gt;get&amp;lt;/prop&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/props&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/property&amp;gt;&lt;br /&gt;
&amp;lt;/bean&amp;gt;&lt;/DIV&gt;&lt;br /&gt;
위와 같이 get이라는 method로 설정하게되면 내부적으로 'Recurrsive'가 발생하게 되어 종국에는 'Failed to invoke last-modified method'라는 메시지 발생.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;STRONG&gt;&lt;U&gt;분석&lt;/U&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;br /&gt;우선&amp;nbsp; org/springframework/web/servlet/mvc/multiaction/MultiActionController.java의 registerLastModifiedMethodIfExists&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;private void registerLastModifiedMethodIfExists(Object delegate, &lt;FONT color=#e31600&gt;Method method&lt;/FONT&gt;) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Look for corresponding LastModified method.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Method lastModifiedMethod = delegate.getClass().getMethod(&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#e31600&gt;method.getName() + LAST_MODIFIED_METHOD_SUFFIX&lt;/FONT&gt;,&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new Class[] {HttpServletRequest.class});&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Put in cache, keyed by handler method name.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#e31600&gt;this.lastModifiedMethodMap.put(method.getName(), lastModifiedMethod);&lt;br /&gt;
&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (logger.isDebugEnabled()) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logger.debug(&quot;Found last modified method for action method [&quot; + method + &quot;]&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (NoSuchMethodException ex) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // No last modified method. That's ok.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
method.getName() + LAST_MODIFIED_METHOD_SUFFIX 부분만 보고 생각해 보면 method의 객체가 get이라고 볼때 get에 LAST_MODIFIED_METHOD_SUFFIX인 LastModified를 조합해 getLastModified method 객체를 map에 넣게 됩니다.&lt;br /&gt;
&lt;br /&gt;즉, 애초의 의도는 사용자 actionController class에 getXXXLastModified(..)라는 method가 존재하면 존재하는 method를 map에 넣고 그렇지 않으면 skip하는 구조인데 잘못된 action mapping으로 아래 언급하는 getLastModified method 객체를 추가하게되고, springframework의 본래&amp;nbsp;getLastModified method를 call method로 넣는 바람에 재귀호출이 일어나는 구조적 문제를 야기합니다.&lt;br /&gt;
&lt;br /&gt;org/springframework/web/servlet/mvc/multiaction/MultiActionController.java의 getLastModified&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;/**&lt;br /&gt;
&amp;nbsp;* Try to find an XXXXLastModified method, where XXXX is the name of a handler.&lt;br /&gt;
&amp;nbsp;* Return -1, indicating that content must be updated, if there's no such handler.&lt;br /&gt;
&amp;nbsp;* @see org.springframework.web.servlet.mvc.LastModified#getLastModified(HttpServletRequest)&lt;br /&gt;
&amp;nbsp;*/&lt;br /&gt;
public long getLastModified(HttpServletRequest request) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; String handlerMethodName = this.methodNameResolver.getHandlerMethodName(request);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Method lastModifiedMethod = (Method) this.lastModifiedMethodMap.get(handlerMethodName);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (lastModifiedMethod != null) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // invoke the last-modified method&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#e31600&gt;Long wrappedLong = (Long) lastModifiedMethod.invoke(this.delegate, new Object[] { request });&lt;br /&gt;
&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return wrappedLong.longValue();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (Exception ex) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We encountered an error invoking the last-modified method.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // We can't do anything useful except log this, as we can't throw an exception.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logger.error(&quot;Failed to invoke last-modified method&quot;, ex);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // if we had a lastModified method for this request&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch (NoSuchRequestHandlingMethodException ex) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // No handler method for this request. This shouldn't happen, as this&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // method shouldn't be called unless a previous invocation of this class&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // has generated content. Do nothing, that's OK: We'll return default.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return -1L;&lt;br /&gt;
}&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
위와 같은 상황에서 getLastModified(..) 호출이 발생했고 해당 request의 handlerMethodName이 get이라고 한다면 결국에 lastModifiedMethod은 getLastModifiedMethod가 되며 이 method는 위에서 언급 했듯이 지금 유입된 자기 자신이므로 재귀호출하게됩니다.. 무한 반복...&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;참고&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;
만약 제니퍼를 사용하고 있다면 위 case를 'Infinite Recurrsive Call indicated'로 인지하게 되며 'active Thread' 상에 종료되지 않은 요청으로 남게 됩니다.&lt;br /&gt;
&lt;br /&gt;위 case를 인지하기 전까지 'Infinite Recurrsive Call indicated'에 대해서 RequestDispatcher의 forward()/ include()의 무한반복재귀호출로 생각하고 문제 없는 소스만 검토를 했었습니다.&lt;br /&gt;
&lt;br /&gt;@</description>
      <category>JAVA</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/6</guid>
      <comments>https://b.pungjoo.com/entry/Failed-to-invoke-last-modified-method-springframework#entry6comment</comments>
      <pubDate>Thu, 14 Feb 2008 12:27:00 +0900</pubDate>
    </item>
    <item>
      <title>HTTP 1.1 Keep-Alive 기능에 대해</title>
      <link>https://b.pungjoo.com/entry/HTTP-11-Keep-Alive-%EA%B8%B0%EB%8A%A5%EC%97%90-%EB%8C%80%ED%95%B4</link>
      <description>&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;들어 가면서&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;HTTP는 아시다 시피 connection less 방식으로 연결을 매번 끊고 새로 생성하는 구조입니다. 이는 network 비용측면에서 많은 비용을 소비하는 구조입니다.( 최초 연결하기 위한 준비과정을 의미함 ) 그래서 HTTP 1.1부터는 Keep-Alive라는 기능을 지원합니다.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;Keep Alive란?&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;
Keep Alive란 연결된 socket에 IN/OUT의 access가 마지막으로 종료된 시점부터 정의된 시간까지 access가 없더라도 대기하는 구조입니다. 즉 정의된 시간내에 access가 이루어진다면 계속 연결된 상태를 유지할 수 있다는 것 이죠.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;HTTP 下에서 Keep Alive란?&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;HTTP는 앞서 설명드린 것과 같이 connection less방식이라 매번 socket(port)를 열어야 하고 이는 비용적인 측면에서 비효율적인 구조입니다. 해서 keep Alive time out내에 client에서 request를 재 요청하면 socket(port)를 새로 여는 것이 아니라 이미 열려 있는 socket(port)에 전송하는 구조가 됩니다.&lt;/P&gt;
&lt;P&gt;예를 들면 image를 4개를 보여주는 구조에서 client는 동시에 2개의 image만 얻어 올수 있고 1개의 image는 얻는데 2초 걸리고 port를 여는데 1초가 걸린다고 가정.&lt;br /&gt;
&lt;br /&gt;&lt;/P&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;
&lt;OL style=&quot;LIST-STYLE-TYPE: decimal&quot;&gt;
&lt;LI&gt;keep alive : false &lt;br /&gt;
처음 server에 2개의 port를 열고 image를 얻고 client socket의 닫고 ( 3초 ) &lt;br /&gt;
다시 server에 2개의 port를 열고 image를 얻고 client socket을 닫음 ( 3초 ) &lt;br /&gt;
총 6초가 걸림.&lt;br /&gt;
&lt;/LI&gt;
&lt;LI&gt;keep alive : true &lt;br /&gt;
처음 server에 2개의 port를 열고 image를 얻고 ( 3초 ) &lt;br /&gt;
다시 첫번째 요청에서 열어 둔 2개의 port에 2개의 image를 얻음 ( 2초 ) &lt;br /&gt;
keep alive time out이 되었을 때 client의 socet이 닫히거나 browser가 더 이상 얻어 올 것이 없으면 자동으로 닫어 버림. &lt;br /&gt;
총 5초가 걸림. &lt;/LI&gt;&lt;/OL&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;br /&gt;
&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;Keep Alive를 그럼 어떻게 쓸수 있는가?&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;
딱, 잘라서 말하면 개발자 영역에서 할 부분은 전혀 없습니다.&lt;br /&gt;
&lt;/P&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;
&lt;OL&gt;
&lt;LI&gt;client(browser)는 http 1.1을 준수하고 이해 할수 있다고 request에 Connection: Keep-Alive를 넣어서 Server에 전송 &lt;br /&gt;
즉 client는 http 1.1 spec을 구현하고.. &lt;br /&gt;
&lt;/LI&gt;
&lt;LI&gt;server도 http 1.1 spec을 구현하고 keep alive 기능을 활성화하고 keep alive time out을 설정&lt;/LI&gt;&lt;/OL&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;참고&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;client에서 keep alive code를 보내고 server도 kepp alive 기능을 제공할 경우.&lt;br /&gt;
&lt;/P&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;$ telnet pungjoo.com 80&lt;br /&gt;
Trying 121.124.124.74...&lt;br /&gt;
Connected to pungjoo.com.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
GET / HTTP/1.1&lt;br /&gt;
Host: pungjoo.com&lt;br /&gt;
Connection: Keep-Alive 
&lt;P&gt;HTTP/1.1 302 Moved Temporarily&lt;br /&gt;
Date: Tue, 15 Jan 2008 01:32:45 GMT&lt;br /&gt;
Set-Cookie: JSESSIONID=91569ADEF9D501B8071BD59D0DC04E82; Path=/&lt;br /&gt;
Location: &lt;A href=&quot;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&quot;&gt;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&lt;/A&gt;&lt;br /&gt;
Content-Type: text/html;charset=EUC-KR&lt;br /&gt;
Content-Length: 0&lt;br /&gt;
&lt;FONT color=#e31600&gt;Keep-Alive: timeout=5, max=100&lt;br /&gt;
Connection: Keep-Alive&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Connection to pungjoo.com closed by foreign host.&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;위에 Connection to pungjoo.com closed by foreign host. 메시지가 바로 나오는 것이 아니라 5초 후에 나오게 됩니다.&lt;br /&gt;
즉 server/client의 구간은 지속됨을 알수 있습니다.&lt;br /&gt;
&lt;br /&gt;&lt;/P&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;$ telnet pungjoo.com 80&lt;br /&gt;
Trying 121.124.124.74...&lt;br /&gt;
Connected topungjoo.com.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
GET / HTTP/1.1&lt;br /&gt;
Host: pungjoo.com&lt;br /&gt;
Connection: Keep-Alive 
&lt;P&gt;HTTP/1.1 302 Moved Temporarily&lt;br /&gt;
Date: Tue, 15 Jan 2008 01:36:26 GMT&lt;br /&gt;
Set-Cookie: JSESSIONID=2B3EE2FE56868BD9588A7B55C405974B; Path=/&lt;br /&gt;
Location: &lt;A href=&quot;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&quot;&gt;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&lt;/A&gt;&lt;br /&gt;
Content-Type: text/html;charset=EUC-KR&lt;br /&gt;
Content-Length: 0&lt;br /&gt;
Keep-Alive: timeout=5, max=100&lt;br /&gt;
Connection: Keep-Alive&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#e31600&gt;GET / HTTP/1.1&lt;br /&gt;
Host: pungjoo.com&lt;br /&gt;
Connection: Keep-Alive&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;HTTP/1.1 302 Moved Temporarily&lt;br /&gt;
Date: Tue, 15 Jan 2008 01:36:35 GMT&lt;br /&gt;
Set-Cookie: JSESSIONID=E4E3D9B9CFE3693DC5AFC3D6ABDE5564; Path=/&lt;br /&gt;
Location: &lt;A href=&quot;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&quot;&gt;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&lt;/A&gt;&lt;br /&gt;
Content-Type: text/html;charset=EUC-KR&lt;br /&gt;
Content-Length: 0&lt;br /&gt;
&lt;FONT color=#e31600&gt;Keep-Alive: timeout=5, max=99&lt;br /&gt;
Connection: Keep-Alive&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Connection to pungjoo.com closed by foreign host.&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;br /&gt;
위 예제를 보시면 알겠지만 telnet(연결)은 한번 사용했고 GET method를 2번 날렸습니다. 즉 이렇게 할수 있는 이유는 keep alive 기능때문에 가능한 것 입니다.&lt;/P&gt;
&lt;P&gt;참고로 보면 Keep-Alive: timeout=5, max=99 부분에서 max가 감소를 하는 것을 볼수 있는데 이는 최초 연결된 port에 대해서 100회 request를 받겠다는 의미입니다.&lt;/P&gt;
&lt;P&gt;HTTP1.0으로 해 보겠습니다. 즉 keep alive 기능이 없음.&lt;br /&gt;
&lt;/P&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #c1c1c1 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #c1c1c1 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #c1c1c1 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #c1c1c1 1px dashed; BACKGROUND-COLOR: #eeeeee&quot;&gt;$ telnet pungjoo.com 80&lt;br /&gt;
Trying 121.124.124.74...&lt;br /&gt;
Connected to pungjoo.com.&lt;br /&gt;
Escape character is '^]'.&lt;br /&gt;
GET / HTTP/1.0&lt;br /&gt;
Host:&amp;nbsp;pungjoo.com 
&lt;P&gt;HTTP/1.1 302 Moved Temporarily&lt;br /&gt;
Date: Tue, 15 Jan 2008 01:33:56 GMT&lt;br /&gt;
Set-Cookie: JSESSIONID=B4329BFEDB1363BB90FCFA9568DDBF0B; Path=/&lt;br /&gt;
Location: &lt;A href=&quot;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&quot;&gt;http://pungjoo.com/servlet/com.pungjoo.blog2005.Action&lt;/A&gt;&lt;br /&gt;
Content-Type: text/html;charset=EUC-KR&lt;br /&gt;
Content-Length: 0&lt;br /&gt;
Connection: close&lt;/P&gt;
&lt;P&gt;Connection to pungjoo.com closed by foreign host.&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;이번 경우는 response가 날라 오고 바로 'Connection to&amp;nbsp;pungjoo.com closed by foreign host.'로 나와 버립니다. 즉 바로 server/client에서 끊어 버립니다.&lt;/P&gt;
&lt;P&gt;@&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <category>HTTP</category>
      <category>http</category>
      <category>Keep-Alive</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/2</guid>
      <comments>https://b.pungjoo.com/entry/HTTP-11-Keep-Alive-%EA%B8%B0%EB%8A%A5%EC%97%90-%EB%8C%80%ED%95%B4#entry2comment</comments>
      <pubDate>Tue, 15 Jan 2008 00:20:00 +0900</pubDate>
    </item>
    <item>
      <title>FTP에한 고찰 - 작성 중</title>
      <link>https://b.pungjoo.com/entry/FTP%EC%97%90%ED%95%9C-%EA%B3%A0%EC%B0%B0-%EC%9E%91%EC%84%B1-%EC%A4%91</link>
      <description>&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;STRONG&gt;들어가면서&lt;/STRONG&gt;&lt;br /&gt;
&lt;/SPAN&gt;&lt;/U&gt;&lt;br /&gt;
일반적으로 고가용성(HA : High Availability)을 확보하기 위해서 이중화(복수 서비스를 의미함) 구성을 합니다. 이 이중화라는 것을 다시 분리를 하면 load balance / Cluster 두가지를 고려하게 됩니다. 
&lt;P&gt;Load Balance는 부하 분산을 의미하며 cluster는 session 유지를 의미하며 일반적으로 Cluster는 Load Balance의 하부 구조에 속하는 것으로 인식되기도 합니다.&lt;/P&gt;
&lt;P&gt;이런 일련의 HA를 위해서는 유입되는 창구를 단일화 해야 합니다.&lt;br /&gt;
( 단일화된 창구 장애로 인한 문제를 해결하기 위해서는 일반적으로 Stand-by machine을 운용합니다 )&lt;br /&gt;
&lt;br /&gt;&lt;U&gt;&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;고찰에 들어 가면서..&lt;/SPAN&gt;&lt;br /&gt;
&lt;/STRONG&gt;&lt;/U&gt;&lt;br /&gt;
위와 같이 한쪽 Node의 장애를 대비해 즉, HA 확보 차원에서 Node를 2개를 운용하고 있었으나 부분적으로 service가되는 반면 다른 한쪽 측면에서는 서비스를 할수 없었는 문제가 발생한 것은 '유입되는 창구의 단일화'라는 전제가 깨져 버렸기 때문입니다.&lt;/P&gt;
&lt;P&gt;즉, node1로 연결을 한 service는 정상적으로 처리가 되었고 node2로 연결된 serivce는 node2의 장애로 처리가 안된 상태입니다.&lt;/P&gt;
&lt;P&gt;이런 문제를 해결하기 위해서 애초에 '유입 창구' 단일화를 위해서 설정된 L4로 연결을 시켜 놨으면 L4 Member로 등록된 Node1/Node2로 적절히 분배해 주며 장애시에는 장애가 발생된 Node를 격리시키므로서 모든 Request를 정상적인 Node로 한정하게 되어 매끄러운 서비스가 가능했을 겁니다.&lt;/P&gt;
&lt;P&gt;그러나 이런 구성에 있어서 FTP에 대한 L4 balance에는 한가지 문제가 있어 쉽게 L4로 변경할 수 없습니다.&lt;br /&gt;
(솔직히 문제라고 보기는 뭐하지만.. )&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;FTP( File Transfer Protocol )에 대한 고찰&lt;br /&gt;
&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;
FTP specification : &lt;A href=&quot;http://www.faqs.org/rfcs/rfc959.html&quot; rel=nofollow&gt;http://www.faqs.org/rfcs/rfc959.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;FTP는 오랜 역사를 자랑하는 Protocol입니다. rfc959의 경우는 1985년 10월에 마지막 수정된 문서이네요.&lt;/P&gt;
&lt;P&gt;문서를 읽어 보시면 알겠지만, FTP는 control 즉, command(put/get등등)에 대한 의사 소통을 위한 파이프(Stream)와 Data를 전송하기 위한 파이프가 존재하게 됩니다. 파이프는 Port로 대변됩니다.&lt;/P&gt;
&lt;P&gt;알려진 21/20번 port는 command/data 전송 port이며 default는 active라는 mode로 운용됩니다. 다른 Mode로는 Passive Mode가 존재합니다. (참고로 browser를 통한 ftp 접근시에는 default로 Passive Mode로 연결 됩니다.)&lt;/P&gt;
&lt;P&gt;Active Mode에서 연결 개념&lt;/P&gt;
&lt;P&gt;Client는 사용되지 않는 random한 port N(N &amp;gt; 1023)를 통해서 ftp Server의 21port(command)와 연결하며 N+1한 port를 client machine에서 open(listening/ 용도는 data 전송)합니다.&lt;br /&gt;
&lt;br /&gt;이때, client는 ftp server에 listening하고 있는 N+1 port를 알려 주고 client에서 command(put/get)를 날리면(21port로) ftp server는 20port를 통해서 client의 N+1에 연결해 Data를 주고 받는 구조가 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs9/1_tistory_2008_09_11_00_05_48c7e21e4d714?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs9%2F1_tistory_2008_09_11_00_05_48c7e21e4d714%3Foriginal&quot; width=&quot;700&quot; height=&quot;385&quot; alt=&quot;&quot; filename=&quot;activeMode.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/P&gt;
&lt;P&gt;Passive Mode에서 연결 개념&lt;/P&gt;
&lt;P&gt;Client는 사용되지 않는 random한 port N( N &amp;gt; 1023)를 통해서 ftp server의 21port(command)와 연결하며 N+1한 port를 client machine에서 open(listening 용도가 아님 / 용도는 data전송)합니다. &lt;br /&gt;
&lt;br /&gt;이때, active mode와는 다르게 client는 ftp server에 N+1한 port를 알려 주는 것이 아니라 PASV라는 command를 전송하며 ftp server는 random한 port P(P &amp;gt; 1023)를 Open(listening/ 용도는 data 전송)하고 client에서 Open된 p port를 전송합니다.&lt;br /&gt;
&lt;br /&gt;이제 client에서 command(put/get) 날리면(21port로) client의 N+1한 port를 통해서 ftp server의 P port로 연결해 Data를 주고 받는 구조가 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs9/36_tistory_2008_09_11_00_05_48c7e24c965b3?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs9%2F36_tistory_2008_09_11_00_05_48c7e24c965b3%3Foriginal&quot; width=&quot;700&quot; height=&quot;385&quot; alt=&quot;&quot; filename=&quot;passiveMode.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;/P&gt;
&lt;P&gt;결론적으로 Active/Passive Mode의 차이는 Data 전송 Port를&amp;nbsp; '누가 Listening하냐'의 차이입니다.&lt;br /&gt;
&lt;br /&gt;즉, Active mode에서 Push는 ftp server의 20port가 client의 N+1 port에 data를 날리는 구조이고 Passive mode에서 Push는 client의 N+1 Port가 ftp Server의 P port에 data를 날리는 구조입니다.&lt;/P&gt;
&lt;P&gt;일반적으로 이런 연결하는 주체에 대해서 network 용어로 in/out bound라고 합니다.&lt;br /&gt;
가끔 방화벽 얘기를 할때 'A machine에 대해서 B machine의 inbound가 열렸느니 닫혔느니' 하죠.&lt;br /&gt;
&lt;br /&gt;@&lt;/P&gt;</description>
      <category>미분류</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/1</guid>
      <comments>https://b.pungjoo.com/entry/FTP%EC%97%90%ED%95%9C-%EA%B3%A0%EC%B0%B0-%EC%9E%91%EC%84%B1-%EC%A4%91#entry1comment</comments>
      <pubDate>Thu, 22 Nov 2007 14:07:00 +0900</pubDate>
    </item>
    <item>
      <title>call by value VS call by reference 추가 설명</title>
      <link>https://b.pungjoo.com/entry/call-by-value-VS-call-by-reference-%EC%B6%94%EA%B0%80-%EC%84%A4%EB%AA%85</link>
      <description>&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;들어가면서&lt;/span&gt;&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;
java는 call by value일까요? call by&amp;nbsp;reference일 까요?&lt;/p&gt;
&lt;p&gt;책이나 여타 문서를 보면 대부분 call by value라고 쓰여 있고 개중에는 반쪽짜리 call by&amp;nbsp;reference라고 쓰여 있습니다. &lt;br /&gt;
어떤 책/문서에는 call by&amp;nbsp;reference라고 쓰여 있기도 하고...&lt;br /&gt;
&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;strong&gt;&lt;u&gt;퀴즈&lt;/u&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px dashed; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package com.pungjoo.edu;&lt;br /&gt;
&lt;br /&gt;
public class ReferenceVSvalue {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private String message = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private int data = 0;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public ReferenceVSvalue(String message, int init) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.message = message;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.data = init;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void plusType1(ReferenceVSvalue r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r.data++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void plusType2(ReferenceVSvalue r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r = new ReferenceVSvalue(&quot;두번째 객체&quot;, 50);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r.data++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void print(ReferenceVSvalue r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(r.message + &quot;의 value : &quot; + r.data);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReferenceVSvalue instance = new ReferenceVSvalue(&quot;첫번째 객체&quot;, 20);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; plusType1(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; plusType2(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;결과&lt;/span&gt;&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;
결과가 어떻게 나올까요?&lt;br /&gt;
첫번째 객체의 value : 21&lt;br /&gt;
첫번째 객체의 value : 21&lt;br /&gt;
&amp;nbsp;&lt;br /&gt;
첫번째 객체의 value : 21&lt;br /&gt;
두번째 객체의 value : 51&lt;br /&gt;
&lt;br /&gt;
위 소스에 call by value라고 가정해 보면 (가정이 아니 결론이지만..) main method의 마지막 print()까지 흘러 가고 내부적으로 GC가 발생하면 어떤 객체가 소멸되어야 할까요? '&lt;font color=&quot;#0000ff&quot;&gt;new ReferenceVSvalue(&quot;두번째 객체&quot;, 50);&lt;/font&gt;'가 소멸될 것입니다. 반대로 call by&amp;nbsp;reference라고 한다면 &lt;font color=&quot;#0000ff&quot;&gt;'new ReferenceVSvalue(&quot;첫번째 객체&quot;, 20);&lt;/font&gt;'가 소멸될 것입니다.&amp;nbsp;&lt;/p&gt;
finalize()를 추가해서 어떤 객체가 소멸되는지 알아 보겠습니다.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;finalize()를 추가한 예제&lt;/span&gt;&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px dashed; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
package com.pungjoo.edu;&lt;br /&gt;
&lt;font color=&quot;#993366&quot;&gt;&lt;strong&gt;&lt;br /&gt;
import java.util.Date;&lt;/strong&gt;&lt;/font&gt; 
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&lt;br /&gt;
public class ReferenceVSvalue {&lt;br /&gt;
&lt;strong&gt;&lt;font color=&quot;#993366&quot;&gt;&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&lt;strong&gt;&lt;font color=&quot;#993366&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private Date createDate = null;&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private String message = null;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private int data = 0;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ReferenceVSvalue(String message, int init) {&lt;br /&gt;
&lt;strong&gt;&lt;font color=&quot;#993366&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;createDate = new Date();&lt;/font&gt;&lt;/strong&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.message = message;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.data = init;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&lt;strong&gt;&lt;font color=&quot;#993366&quot;&gt;&lt;/font&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&lt;strong&gt;&lt;font color=&quot;#993366&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void finalize() throws Throwable {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.err.println(createDate + &quot;에 생성된 객체가 GC가 되려고 합니다. (&quot; + message + &quot;)&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; super.finalize();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void plusType1(ReferenceVSvalue r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r.data++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void plusType2(ReferenceVSvalue r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r = new ReferenceVSvalue(&quot;두번째 객체&quot;, 50);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r.data++;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void print(ReferenceVSvalue r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(r.message + &quot;의 value : &quot; + r.data);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ReferenceVSvalue instance = new ReferenceVSvalue(&quot;첫번째 객체&quot;, 20);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; plusType1(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; plusType2(instance);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(instance);&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;&lt;font color=&quot;#993366&quot;&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // 아무 의미 없음.. 그냥 sleep&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.gc();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Thread.sleep(1000 * 1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (InterruptedException e) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.printStackTrace();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&lt;/strong&gt;&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;/p&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;u&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 14pt&quot;&gt;결과&lt;/span&gt;&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;

&lt;div style=&quot;BORDER-BOTTOM: #cbcbcb 1px dashed; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-BOTTOM: 10px; BACKGROUND-COLOR: #ffffff; PADDING-LEFT: 10px; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-TOP: 10px&quot; class=&quot;txc-textbox&quot;&gt;
첫번째 객체의 value : 21&lt;br /&gt;
첫번째 객체의 value : 21&lt;br /&gt;
&lt;font color=&quot;#ff0000&quot;&gt;Tue Apr 24 09:36:26 KST 2007에 생성된 객체가 GC가 되려고 합니다. (두번째 객체)&lt;/font&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;br /&gt;
위에서 설명드린 것 처럼 GC되는 객체는 '두번째 객체'로 나오는 군요.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
따라서 plusType2 method에서 'new ReferenceVSvalue(&quot;두번째 객체&quot;, 50);' 은 자신의 method에서만 유효한 값이라는 의미가 됩니다.&lt;br /&gt;
&lt;br /&gt;
@</description>
      <category>JAVA</category>
      <category>Reference</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/8</guid>
      <comments>https://b.pungjoo.com/entry/call-by-value-VS-call-by-reference-%EC%B6%94%EA%B0%80-%EC%84%A4%EB%AA%85#entry8comment</comments>
      <pubDate>Tue, 24 Apr 2007 15:48:00 +0900</pubDate>
    </item>
    <item>
      <title>reference VS value</title>
      <link>https://b.pungjoo.com/entry/reference-VS-value</link>
      <description>&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;U&gt;들어가면서&lt;/U&gt;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;br /&gt;
자바에서 call by reference일까요 call by value일까요?&lt;br /&gt;
&lt;br /&gt;&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;예제 소스&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1&amp;nbsp; public class CBRTest {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 2&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void change(StringBuffer r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r.delete(0, 1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r.append(&quot;10&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 7&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; static void change2(StringBuffer r) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r = new StringBuffer(&quot;15&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 11&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static void main(String [] args) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 12&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuffer s = new StringBuffer(&quot;5&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 13&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; change(s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; change2(s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 17&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(s);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 18&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 20&amp;nbsp; }&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;&lt;STRONG&gt;결과&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/U&gt;&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;5&lt;br /&gt;
10&lt;br /&gt;
10&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;메모리 구조로 풀어본 value&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;A / line 12 : new StringBuffer(&quot;5&quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default 크기만큼의 Memory를 할당 받아 0x35h(문자 5를 의미함)를 기록함.. &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 이 문자열은 memory address 0x0000h ~ 0x000fh를 차지함.&lt;br /&gt;
&lt;br /&gt;B&amp;nbsp; / line 12 : StringBuffer s = &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s를 의미하는 memory address 0x0100h에 A에서 얻은 주소의 시작점을 기록함..&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 즉, 0x0100h에는 0x0000h가 들어 감.&lt;br /&gt;
&lt;br /&gt;//change(s);&lt;br /&gt;
C / line&amp;nbsp; 3 : StringBuffer r&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r을 의미하는 memory address 0x0200h에 0x0000h를 기록함&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; line&amp;nbsp; 4 : r(0x0200h)이 가르키고 있는 0x0000h의 memory에서 문자 삭제 ( delete ... )&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; line&amp;nbsp; 5 : r(0x0200h)이 가르키고 있는 0x0000h의 memory에서 문자 추가 ( append ... )&lt;br /&gt;
&lt;br /&gt;//change2(s);&lt;br /&gt;
D / line&amp;nbsp; 8 : StringBuffer r&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r을 의미하는 memory address 0x0300h에 0x0000h를 기록함&lt;br /&gt;
&lt;br /&gt;E / line&amp;nbsp; 9 : new StringBuffer(&quot;15&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default 크기만큼의 Memory를 할당 받아 0x31h, 0x35h(문자 1과5를 의미함)를 기록함.. &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 이 문자열은 memory address 0x0400h ~ 0x040fh를 차지함.&lt;br /&gt;
&lt;br /&gt;F / line&amp;nbsp; 9 : r =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; D에서 정의한 r의 주소에 E에서 얻은 주소의 시작점을 기록함.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 즉, 0x0300h에는 0x0400h가 들어 감.&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 14pt&quot;&gt;메모리 구조로 풀어본 reference&lt;/SPAN&gt;&lt;/U&gt;&lt;/STRONG&gt;&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #cbcbcb 1px dashed; PADDING-RIGHT: 10px; BORDER-TOP: #cbcbcb 1px dashed; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #cbcbcb 1px dashed; PADDING-TOP: 10px; BORDER-BOTTOM: #cbcbcb 1px dashed; BACKGROUND-COLOR: #ffffff&quot;&gt;A / line 12 : new StringBuffer(&quot;5&quot;)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default 크기만큼의 Memory를 할당 받아 0x35h(문자 5를 의미함)를 기록함.. &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 이 문자열은 memory address 0x0000h ~ 0x000fh를 차지함.&lt;br /&gt;
&lt;br /&gt;B&amp;nbsp; / line 12 : StringBuffer s = &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s를 의미하는 memory address 0x0100h에 A에서 얻은 주소의 시작점을 기록함..&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 즉, 0x0100h에는 0x0000h가 들어 감.&lt;br /&gt;
&lt;br /&gt;//change(s);&lt;br /&gt;
C / line&amp;nbsp; 3 : StringBuffer r&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r을 의미하는 memory address는 실 매개 변수(actual parameter)와 동일하므로 0x0100h address를&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 그대로 사용함.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; line&amp;nbsp; 4 : r(0x0100h)이 가르키고 있는 0x0000h의 memory에서 문자 삭제 ( delete ... )&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; line&amp;nbsp; 5 : r(0x0100h)이 가르키고 있는 0x0000h의 memory에서 문자 추가 ( append ... )&lt;br /&gt;
&lt;br /&gt;//change2(s);&lt;br /&gt;
D / line&amp;nbsp; 8 : StringBuffer r&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r을 의미하는 memory address는 실 매개 변수(actual parameter)와 동일하므로 0x0100h address를&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 그대로 사용함.&lt;br /&gt;
&lt;br /&gt;E / line&amp;nbsp; 9 : new StringBuffer(&quot;15&quot;);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; default 크기만큼의 Memory를 할당 받아 0x31h, 0x35h(문자 1과5를 의미함)를 기록함.. &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 이 문자열은 memory address 0x0400h ~ 0x040fh를 차지함.&lt;br /&gt;
&lt;br /&gt;F / line&amp;nbsp; 9 : r =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; D에서 정의한 r의 주소에 E에서 얻은 주소의 시작점을 기록함.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 즉, 0x0100h에는 0x0400h가 들어 감.&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
@</description>
      <category>JAVA</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/7</guid>
      <comments>https://b.pungjoo.com/entry/reference-VS-value#entry7comment</comments>
      <pubDate>Wed, 7 Feb 2007 15:39:00 +0900</pubDate>
    </item>
    <item>
      <title>[Linux] Memory 예제</title>
      <link>https://b.pungjoo.com/entry/Linux-Memory-%EC%98%88%EC%A0%9C</link>
      <description>&lt;P style=&quot;MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px&quot;&gt;앞으로 설명할 부분에서는 swap사용, cpu 응답 속도, disk I/O 등등 여러가지 Memory로 인해 파생되는 문제들은&lt;br /&gt;
논외로합니다. 우선 이해하기 쉽게 Memory의 내용에만 충실합시다.&lt;br /&gt;

&lt;P&gt;&lt;/P&gt;&lt;div class=&quot;imageblock &quot; style=&quot;display:inline;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/28_tistory_2008_09_21_11_49_48d5b62cec680?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F28_tistory_2008_09_21_11_49_48d5b62cec680%3Foriginal&quot; width=&quot;584&quot; height=&quot;163&quot; alt=&quot;&quot; filename=&quot;excel_sheet.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
[자료 1]&lt;br /&gt;
&lt;br /&gt;Linux에서 memory 관련된 정보를 얻는 command 및 방법은 많겠지만 free라는 command로 나온 값을 약간 가공하면 [자료 1]과 같은 모습입니다. 위 Data는 10분에 1번씩 찍은 값입니다. &lt;br /&gt;
&lt;br /&gt;[자료 1]과 같은 data를 놓고 볼때 흔히들 단편적으로 free라는 항목만 보고 total대비 수치가 낮기 때문에 memory가 부족한 것으로 오해를 합니다. 즉, [자료 2] 처럼..&lt;br /&gt;
&lt;div class=&quot;imageblock &quot; style=&quot;display:inline;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/7_tistory_2008_09_21_11_49_48d5b62b7bea0?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F7_tistory_2008_09_21_11_49_48d5b62b7bea0%3Foriginal&quot; width=&quot;663&quot; height=&quot;326&quot; alt=&quot;&quot; filename=&quot;default_free_used.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
[자료 2]&lt;br /&gt;
&lt;br /&gt;[자료 2]에서 푸른색 부분이 used이며 붉은색 부분이 free부분입니다.&amp;nbsp;&lt;br /&gt;
[자료 2]을 보고 상식적으로 생각해 보면 어떻게 시스템이 한쉬도 숨 없이 99%이상 Memory를 사용할 수 있을까요?&lt;br /&gt;
&lt;br /&gt;이상하죠?.. &lt;br /&gt;
&lt;br /&gt;자.. 그럼 동일한 data를 갖고 세부적으로 표현해 보겠습니다.&lt;br /&gt;
&lt;div class=&quot;imageblock &quot; style=&quot;display:inline;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/29_tistory_2008_09_21_11_49_48d5b62f466ef?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F29_tistory_2008_09_21_11_49_48d5b62f466ef%3Foriginal&quot; width=&quot;662&quot; height=&quot;327&quot; alt=&quot;&quot; filename=&quot;free_shared_buffers_cached.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
[자료 3]&lt;br /&gt;
&lt;br /&gt;그냥 위에 이상하다라고 언급한 그림과 비교해 '아.. 뭔가 역동 적으로 사용하는구나'라고 느끼면 됩니다.&lt;br /&gt;
&lt;br /&gt;[자료 3]의 free라는 항목은 [자료 2]의 하단의 붉은색과 같은 부분입니다.&lt;br /&gt;
[자료 3]에서 shared 부분은 값이 0이기 때문에 표기하지 않았습니다.&lt;br /&gt;
[자료 3]에서 [자료 2]와 대비해서 buffers/cached가 생겼습니다.&lt;br /&gt;
&lt;br /&gt;실제로 &lt;FONT color=#ff0000&gt;Total Memory - Free Memory =&amp;nbsp;사용중인 Memory&lt;/FONT&gt;가 맞습니다. 그러나 그 사용중이다라고 하는 Memory가 O/S 영역에서 사용되는 부분도 포함하고 있다라는 것이 문제입니다.&lt;br /&gt;
&lt;br /&gt;즉 O/S 영역에서 사용되고 있다라는 부분이 buffers/cached입니다. 당연히 O/S도 Memory하에서 작동하니까 Memory가 필요한것은 자명한 사실이지만, O/S는 최적의 성능을 보장하기 위해서 buffers/cached를 사용합니다. [자료 3]변화의 폭이 심한 cached의 용도는 대부분이 I/O의 성능을 보장하기 위해서 disk에서 읽은 값은 memory에 저장하는 부분입니다.&lt;br /&gt;
&lt;br /&gt;위와 같은 연유에 Application에서 가용한 Memory는 buffers/cached부분도 포함해야 합니다.&lt;br /&gt;
그래서 Application에서 사용중인 Memory는 [자료 3]에서 붉은색으로 표기된 부분이 됩니다.&lt;br /&gt;
&lt;br /&gt;&lt;div class=&quot;imageblock &quot; style=&quot;display:inline;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/5_tistory_2008_09_21_11_49_48d5b630d9467?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F5_tistory_2008_09_21_11_49_48d5b630d9467%3Foriginal&quot; width=&quot;637&quot; height=&quot;326&quot; alt=&quot;&quot; filename=&quot;office_hours.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
[자료 4]&lt;br /&gt;
&lt;br /&gt;[자료 4]는 [자료 3] 부분에서 업무시간을&amp;nbsp;나타냅니다. 즉, 업무시간내에서는 대략 적으로 Memory를 87% ~ 90%를 지속적으로 사용하는 것을 보실 수 있습니다. ( 점심 시간에는 사용량이 감소합니다. )&lt;br /&gt;
&lt;br /&gt;@</description>
      <category>미분류</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/5</guid>
      <comments>https://b.pungjoo.com/entry/Linux-Memory-%EC%98%88%EC%A0%9C#entry5comment</comments>
      <pubDate>Thu, 13 Jul 2006 16:33:00 +0900</pubDate>
    </item>
    <item>
      <title>메모리 할당 개념, fragment</title>
      <link>https://b.pungjoo.com/entry/%EB%A9%94%EB%AA%A8%EB%A6%AC-%ED%95%A0%EB%8B%B9-%EA%B0%9C%EB%85%90-fragment</link>
      <description>&lt;P&gt;'크기가 맞으면 이전 메모리를 배정해 줄수도 있을겁니다'라는 의미에서 fragment 의미에 대해서 언급하고자 합니다. 일반적으로 o/s는 page 단위로 memory를 관리(할당/해제) 합니다. &lt;br /&gt;
&lt;br /&gt;o/s가 기동되고 내부 memory 관리는 기본적으로 언급했듯이 page 단위로 할당하며 요청되는 size에 맞는 page는 memory 주소가 일련하게 연속되어야 할당을 받을 수 있습니다.&lt;br /&gt;
&lt;br /&gt;예를 들어 사용하고 있는 o/s의 page단위가 8k이고 실 memory가 800k라고 할때 (생각하기 쉽게. 잡다한 부분은 제외하고. 아주 적죠) application에서 10byte의 memory를 요구하면 1 page를 할당해 줍니다. 당연히 size는 8k이겠죠. 이런 개념으로 9k가 되는 size를 요구해도 2 page 할당 즉, 16k를 내부적으로 사용하게됩니다. 7k는 공중에 붕 뜬 공간이 되겠지요.&lt;/P&gt;
&lt;P&gt;위 제시한 memory 공간에서 아래와 같이 현재 사용중이라고 생각해 봅시다.&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/9_tistory_2008_09_21_11_29_48d5b19526d24?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F9_tistory_2008_09_21_11_29_48d5b19526d24%3Foriginal&quot; width=&quot;234&quot; height=&quot;353&quot; alt=&quot;&quot; filename=&quot;page1.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
위 memory 보면 사용중인 page가 45개이며 35개 page는 사용 가능한 상태입니다. 즉, 일반적으로 보면 8k * 35 = 280k를 application에서 사용 가능하다고 생각하지만 답은 '그때 그때 달라요'입니다. 만약 요청되는 size가 1byte~24k 안에 속한다면 문제 없이 할당을 해 줄수 있지만 만약 30k가 필요한 상태라면 위 구조에서는 일련하게 사용하지 않는 memory가 없기때문에 할당을 해 줄수 없는 상태가 발생합니다. 그래서 memory 관리 알고리즘에 의거해 수시로 중간 중간 구멍난(fragment) 부분을 한쪽으로 이동시켜 일련되게 미사용 memory 공간을 확보하는 과정을 수행하게 됩니다.&lt;br /&gt;
&lt;br /&gt;그러나 이러한 과정이 그리 녹녹한건 아닙니다. 현재 사용중인 memory pointer를 빈번하게 움직일 수 없기 때문에 할당은 받았으나 정의된 시간동안 사용하지 않는 부분에 한해서 이루어지게 됩니다. 이해 하기 쉽게 process가 idle 상태라지만 가능하기 때문에 바쁜 process에서 점유하고 있는 memory는 중간 중간 구멍난 상태로 memory를 사용하게 됩니다. (idle일때만 가능한것은 아니나 이해하기 쉽게 한정합니다.)&lt;br /&gt;
&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/4_tistory_2008_09_21_11_29_48d5b19569140?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F4_tistory_2008_09_21_11_29_48d5b19569140%3Foriginal&quot; width=&quot;229&quot; height=&quot;171&quot; alt=&quot;&quot; filename=&quot;page2.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
흔히 우린 disk 조각 모음을 하지요? 그 부분도 동일한 의미로 생각하시면 됩니다. 또한 예를 들어 내용은 10byte이지만 Windows의 경우 속성에서 보면 '크기'와 '디스크 할당 크기'로 구분해 관리함을 보실 수 있을 겁니다.(이 부분이 page 단위)&lt;/P&gt;
&lt;P&gt;위 관점에서 좀 확장해서 page 단위가 8k이고 실 memory는 80k일때 500byte짜리 8개일때는 당연히 아래와 같습니다.&lt;div class=&quot;imageblock center&quot; style=&quot;text-align: center; clear: both;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/tistoryfile/fs8/30_tistory_2008_09_21_11_29_48d5b1958d69f?original&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Ftistoryfile%2Ffs8%2F30_tistory_2008_09_21_11_29_48d5b1958d69f%3Foriginal&quot; width=&quot;228&quot; height=&quot;84&quot; alt=&quot;&quot; filename=&quot;page3.jpg&quot; filemime=&quot;&quot;/&gt;&lt;/div&gt;
&lt;br /&gt;
즉, 작은 size가 빈번하게 많이 사용되는 application이라면 실 memory가 넉넉해도 낭비가 심하다는 겁니다. 위 내용으로 보면 실제 500byte * 8 = 4,000 byte만 필요한데 64k를 사용하는 즉, 61,536 byte는 절대 사용할 수 없는 공간으로 남게 됩니다.&lt;/P&gt;
&lt;P&gt;@&lt;/P&gt;</description>
      <category>미분류</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/4</guid>
      <comments>https://b.pungjoo.com/entry/%EB%A9%94%EB%AA%A8%EB%A6%AC-%ED%95%A0%EB%8B%B9-%EA%B0%9C%EB%85%90-fragment#entry4comment</comments>
      <pubDate>Wed, 26 Oct 2005 17:12:00 +0900</pubDate>
    </item>
    <item>
      <title>standard output and standard error</title>
      <link>https://b.pungjoo.com/entry/standard-output-and-standard-error</link>
      <description>&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 18pt&quot;&gt;들어 가면서&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;우리들에게 입력과 출력을 담당하는 디바이스가 점점 많아지고 있습니다. 이런 입/출력 디바이스 중에 표준 출력에 대해서 알아 봅시다. 더불어&amp;nbsp;표준 오류도...&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 18pt&quot;&gt;경험&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;쉘(shell) script를 보면 끝자락에 '&lt;FONT color=#e31600&gt;&lt;STRONG&gt;&amp;gt; /dev/null&amp;nbsp; 2&amp;gt;&amp;amp;1&lt;/STRONG&gt;&lt;/FONT&gt;' 같은 이상 야릇한 기호가 들어 있는 경우가 있습니다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 18pt&quot;&gt;&lt;STRONG&gt;풀이&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;'&amp;gt;'의 의미는 좌측에서 행해진 결과를 '&amp;gt;'를 기준으로 우측으로 보낸다는 의미입니다.&lt;br /&gt;
'&amp;gt; /dev/null' 은 결국 좌측에서 행해진 결과를 우측인 '널 디바이스'에게 보낸다는 것이죠. 즉 허공에 날린다....&lt;br /&gt;
&lt;br /&gt;그런데 이때&amp;nbsp;중요한 표준 오류에 대해서&amp;nbsp;간과하는 경향이 있습니다. 즉, 표준 출력만&amp;nbsp;알고 표준 오류는 모른다는 것이죠. 이클립스 같은 IDE를 사용하다 보면 오류 부분이 '붉은색(정의 하기 나름이겠지만)'으로 보이는 경험을 했을 것입니다. 이 부분은 일반적으로 System.err.print..(); 을 통해 출력한 내용입니다. logging을 사용하고 있다면 로깅 레벨에 따라서 붉게 표기가 되는 경우가 있겠죠..&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;SPAN style=&quot;FONT-SIZE: 18pt&quot;&gt;&lt;U&gt;예제&lt;/U&gt;&lt;/SPAN&gt;&lt;br /&gt;
&lt;/STRONG&gt;
&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #eeeeee 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #eeeeee 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #eeeeee 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #eeeeee 1px solid; BACKGROUND-COLOR: #eeeeee&quot;&gt;&lt;FONT face=굴림체&gt;[pungjoo@do1 /home/pungjoo/test]$ ls -la&lt;br /&gt;
합계 12&lt;br /&gt;
drwxrwxr-x&amp;nbsp;&amp;nbsp;&amp;nbsp; 2 pungjoo&amp;nbsp; pungjoo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4096&amp;nbsp; 4월 21 08:05 .&lt;br /&gt;
drwx------&amp;nbsp;&amp;nbsp;&amp;nbsp; 9 pungjoo&amp;nbsp; pungjoo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4096&amp;nbsp; 4월 21 07:56 ..&lt;br /&gt;
-rw-rw-r--&amp;nbsp;&amp;nbsp;&amp;nbsp; 1 pungjoo&amp;nbsp; pungjoo&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 150&amp;nbsp; 4월 21 08:04 Test.java&lt;br /&gt;
[pungjoo@do1 /home/pungjoo/test]$ cat Test.java&lt;br /&gt;
public&amp;nbsp; class&amp;nbsp;&amp;nbsp; Test {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&amp;nbsp; static void main(String[] args) {&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println( &quot;표준 출력&quot; );&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.err.println( &quot;표준 에러&quot; );&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
}&lt;/FONT&gt;&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
위와 같은 예제를 평상시 처럼 실행해 보겠습니다.&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #eeeeee 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #eeeeee 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #eeeeee 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #eeeeee 1px solid; BACKGROUND-COLOR: #eeeeee&quot;&gt;&lt;FONT face=굴림체&gt;[pungjoo@do1 /home/pungjoo/test]$ java Test&lt;br /&gt;
표준 출력&lt;br /&gt;
표준 에러&lt;/FONT&gt;&lt;br /&gt;
&lt;FONT face=굴림체&gt;[pungjoo@do1 /home/pungjoo/test]$ &lt;/FONT&gt;&lt;br /&gt;
&lt;/DIV&gt;&lt;br /&gt;
이번에는 표준 출력에 대한 이상 야릇한 문자열을 넣어 실행해 보겠습니다.&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #eeeeee 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #eeeeee 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #eeeeee 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #eeeeee 1px solid; BACKGROUND-COLOR: #eeeeee&quot;&gt;&lt;FONT face=굴림체&gt;[pungjoo@do1 /home/pungjoo/test]$ java Test &lt;FONT color=#e31600&gt;2&amp;gt; error.txt&lt;/FONT&gt;&lt;br /&gt;
표준 출력&lt;br /&gt;
[pungjoo@do1 /home/pungjoo/test]$ cat error.txt&lt;br /&gt;
표준 에러&lt;br /&gt;
[pungjoo@do1 /home/pungjoo/test]$ &lt;/FONT&gt;&lt;br /&gt;
&lt;/DIV&gt;'2&amp;gt; error.txt'를 추가를 하고 실행하니 '표준 출력'만 표기가 되고 있는 것을 볼 수 있습니다. 또한 error.txt를 보면 출력되지 않았던 '표준 에러'라는 문자열이 보입니다.&lt;br /&gt;
&lt;br /&gt;이번에는 다른 문자열을 넣어 실행해 보겠습니다.&lt;br /&gt;

&lt;DIV class=txc-textbox style=&quot;BORDER-RIGHT: #eeeeee 1px solid; PADDING-RIGHT: 10px; BORDER-TOP: #eeeeee 1px solid; PADDING-LEFT: 10px; PADDING-BOTTOM: 10px; BORDER-LEFT: #eeeeee 1px solid; PADDING-TOP: 10px; BORDER-BOTTOM: #eeeeee 1px solid; BACKGROUND-COLOR: #eeeeee&quot;&gt;&lt;FONT face=굴림체&gt;[pungjoo@do1 /home/pungjoo/test]$ java Test &lt;FONT color=#e31600&gt;1&amp;gt; out.txt&lt;/FONT&gt;&lt;br /&gt;
표준 에러&lt;br /&gt;
[pungjoo@do1 /home/pungjoo/test]$ cat out.txt&lt;br /&gt;
표준 출력&lt;br /&gt;
[pungjoo@do1 /home/pungjoo/test]$ &lt;/FONT&gt;&lt;br /&gt;
&lt;/DIV&gt;이번에는 '1&amp;gt; out.txt'를 추가하고 실행하니 위와는 반대로 '표준 에러'만 표기 되고 out.txt에 '표준 출력'이라는 문자열이 들어가 있는 것을 볼 수 있습니다.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;STRONG&gt;&lt;U&gt;&lt;SPAN style=&quot;FONT-SIZE: 18pt&quot;&gt;정리&lt;/SPAN&gt;&lt;br /&gt;
&lt;/U&gt;&lt;/STRONG&gt;&lt;FONT color=#e31600&gt;1&amp;gt; /tmp/log.txt&lt;/FONT&gt;&amp;nbsp;는 표준 출력에 해당하는 디바이스를 화면이 아닌 file로 변경한 것이고&lt;br /&gt;
&lt;FONT color=#e31600&gt;2&amp;gt; &lt;FONT size=+0&gt;/tmp/log.txt&lt;/FONT&gt;&lt;/FONT&gt; 는 표준 오류에 해당하는 디바이스를 화면이 아닌 file로 변경한 것입니다.&lt;br /&gt;
&lt;FONT color=#e31600&gt;&amp;gt; /tmp/log.txt 2&amp;gt;&amp;amp;1&lt;/FONT&gt; 는 표준 출력/ 표준 오류를 표준 디바이스에서 /tmp/log.txt file로 변경한 것입니다.&lt;br /&gt;
&lt;br /&gt;@</description>
      <category>미분류</category>
      <author>pungjoo.kim</author>
      <guid isPermaLink="true">https://b.pungjoo.com/9</guid>
      <comments>https://b.pungjoo.com/entry/standard-output-and-standard-error#entry9comment</comments>
      <pubDate>Thu, 21 Apr 2005 20:24:00 +0900</pubDate>
    </item>
  </channel>
</rss>