Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- urlclassloader
- Proxy
- reflection
- chunked
- singleton
- http/1.1
- toString
- InvocationHandler
- unmodifiableList
- getRequestURI
- Session
- clone
- http
- Java
- Reference
- Keep-Alive
- cookie
- object
- Content-Length
- Transfer-Encoding
Archives
- Today
- Total
pungjoo
작성중 - unmodifiable 본문
0. 들어가면서
지원하지 않는 ~~
Collections class에는 unmodifiable류의 method가 존재합니다. 즉, 특정상황에 return되는 객체의 특정 method는 사용하지 못 하도록 강제하고 싶을 때 사용합니다.
1. 준비 운동
package info.yeonwoo.edu;
import java.util.ArrayList;
import java.util.List;
public class WarmingUp {
private static List<String> getData() {
ArrayList<String> data = new ArrayList<String>();
data.add("pungjoo");
data.add("siyeon");
data.add("siwoo");
return data;
}
public static void main(String[] args) {
List<String> data = getData();
data.add("jihyun");
System.out.println( data);
}
}
import java.util.ArrayList;
import java.util.List;
public class WarmingUp {
private static List<String>
ArrayList<String>
data.add("pungjoo");
data.add("siyeon");
data.add("siwoo");
return data;
}
public static void main(String[] args) {
List<String>
data.add("jihyun");
System.out.println( data);
}
}
결과는
[pungjoo, siyeon, siwoo, jihyun]
그럼 위 붉은 색 LINE을... 이렇게~~~~~~~
package info.yeonwoo.edu;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class WarmingUp {
private static List<String> getData() {
ArrayList<String> data = new ArrayList<String>();
data.add("pungjoo");
data.add("siyeon");
data.add("siwoo");
return Collections.unmodifiableList(data);
}
public static void main(String[] args) {
List<String> data = getData();
data.add("jihyun");
System.out.println(data);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class WarmingUp {
private static List<String>
ArrayList<String>
data.add("pungjoo");
data.add("siyeon");
data.add("siwoo");
return Collections.unmodifiableList(data);
}
public static void main(String[] args) {
List<String>
data.add("jihyun");
System.out.println(data);
}
}
결과는
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1018)
at info.yeonwoo.edu.WarmingUp.main(WarmingUp.java:23)
at java.util.Collections$UnmodifiableCollection.add(Collections.java:1018)
at info.yeonwoo.edu.WarmingUp.main(WarmingUp.java:23)
2. 단순히 생각해 보면 다음과 같이 해 볼 수 있겠죠.
뼈대를 만들어 봅시다..
package info.yeonwoo.edu;
public class Foo {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Foo {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
뼈대를 실행해 봅시다.
package info.yeonwoo.edu;
public class Bar {
public static Foo getData() {
Foo foo = new Foo();
foo.setName("pungjoo");
return foo;
}
public static void main(String[] args) {
Foo foo = getData();
System.out.println( foo.getName());
foo.setName("siyeon");
System.out.println( foo.getName());
}
}
public class Bar {
public static Foo getData() {
Foo foo = new Foo();
foo.setName("pungjoo");
return foo;
}
public static void main(String[] args) {
Foo foo = getData();
System.out.println( foo.getName());
foo.setName("siyeon");
System.out.println( foo.getName());
}
}
결국은 붉은 색 LINE을 어떻게하면 될 듯 한데...
음 단순하게 이런 방식은 어떨까?
public static Foo getData() {
final Foo foo = new Foo();
foo.setName("pungjoo");
Foo ret = new Foo() {
@Override
public void setName(String name) {
throw new UnsupportedOperationException();
}
@Override
public String getName() {
return foo.getName();
}
};
return ret;
}
final Foo foo = new Foo();
foo.setName("pungjoo");
Foo ret = new Foo() {
@Override
public void setName(String name) {
throw new UnsupportedOperationException();
}
@Override
public String getName() {
return foo.getName();
}
};
return ret;
}
결과
pungjoo
Exception in thread "main" java.lang.UnsupportedOperationException
at info.yeonwoo.edu.Bar$1.setName(Bar.java:14)
at info.yeonwoo.edu.Bar.main(Bar.java:32)
Exception in thread "main" java.lang.UnsupportedOperationException
at info.yeonwoo.edu.Bar$1.setName(Bar.java:14)
at info.yeonwoo.edu.Bar.main(Bar.java:32)
원하는 결과는 나왔으나 모든 class의 method를 override를 할 수는 없는 노릇이고...
어쩌구 저쩌구 얼씨구 절씨구~~~~
proxy?.. ( http://pungjoo.tistory.com/17 )
proxy를 사용하기 위해서는 기본조건이 객체는 항상 interface를 사용해야 합니다. 따라서 Foo class를 FooImpl로 변경하고 Foo은 interface화 합니다.
package info.yeonwoo.edu;
public interface Foo {
public String getName();
public void setName(String name);
}
public interface Foo {
public String getName();
public void setName(String name);
}
package info.yeonwoo.edu;
public class FooImpl implements Foo {
private String name;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
public class FooImpl implements Foo {
private String name;
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
}
3. 이런건 어떨까?
package info.yeonwoo.edu;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ObjectUnModify implements InvocationHandler {
private Object obj = null;
private ObjectUnModify(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().startsWith("set")) {
throw new UnsupportedOperationException();
}
Method mm = obj.getClass().getMethod(method.getName(), method.getParameterTypes());
return mm.invoke(obj, args);
}
@SuppressWarnings( { "hiding", "unchecked" } )
final public static <T extends Object>T wrap(T obj) {
return (T) Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new ObjectUnModify(obj));
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ObjectUnModify implements InvocationHandler {
private Object obj = null;
private ObjectUnModify(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().startsWith("set")) {
throw new UnsupportedOperationException();
}
Method mm = obj.getClass().getMethod(method.getName(), method.getParameterTypes());
return mm.invoke(obj, args);
}
@SuppressWarnings( { "hiding", "unchecked" } )
final public static <T extends Object>T
return (T) Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new ObjectUnModify(obj));
}
이쯤에서 Test를 해 봐야겠지요?
package info.yeonwoo.edu;
public class Bar {
public static Foo getData() {
Foo foo = new FooImpl();
foo.setName("pungjoo");
return ObjectUnModify.wrap(foo);
}
public static void main(String[] args) {
Foo foo = getData();
System.out.println( foo.getName());
foo.setName("siyeon");
System.out.println( foo.getName());
}
}
public class Bar {
public static Foo getData() {
Foo foo = new FooImpl();
foo.setName("pungjoo");
return ObjectUnModify.wrap(foo);
}
public static void main(String[] args) {
Foo foo = getData();
System.out.println( foo.getName());
foo.setName("siyeon");
System.out.println( foo.getName());
}
}
결과는
pungjoo
Exception in thread "main" java.lang.UnsupportedOperationException
at info.yeonwoo.edu.ObjectUnModify.invoke(ObjectUnModify.java:22)
at $Proxy0.setName(Unknown Source)
at info.yeonwoo.edu.Bar.main(Bar.java:19)
Exception in thread "main" java.lang.UnsupportedOperationException
at info.yeonwoo.edu.ObjectUnModify.invoke(ObjectUnModify.java:22)
at $Proxy0.setName(Unknown Source)
at info.yeonwoo.edu.Bar.main(Bar.java:19)
어쩌구 저쩌구 해서 저쩌구 어쩌구 이러다 저렇다~~
@
Comments