Java Source 좀 봐주세요.
2010.06.29 02:22
안녕하세요, 해색주입니다. 아래 소스를 이클립스에서 디버깅 하면 돌아가고, 윈도즈 실행창에서 디버깅하면 에러가 납니다. 초보에게 가르침을 주세요~!
/***
업캐스팅과 다운 캐스팅의 테스트
***/
import java.util.Vector;
public class UpDownCasting {
public static void main(String[] args) {
String name = new String("홍길동");
Integer id = new Integer(10000);
Vector v = new Vector();
v.addElement(name);
v.addElement(id);
Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
String str = (String)obj1;
Integer num = (Integer)obj2;
System.out.println("이름: " + str + " 번호:" + num);
String str2 = (String)v.elementAt(0);
Integer num2 = (Integer)v.elementAt(1);
System.out.println("이름: " + str2 + " 번호:" + num2);
}
}
코멘트 10
-
가영아빠
06.29 03:03
-
김강욱
06.29 09:35
환경 변수를 함 보세요.
클래스 파일은 이미 만들어져 있을테고, 그걸 돌렸을 테니, 날 거라고는 Vector 를 못 찾는 것 뿐 일 것 같은데, Vector 를 못 찾는 건, 자바 클래스 패스가 없는 것 아닐지~
-
해색주
06.29 18:11
Eclipse에서는 잘 되는데, 명령 프롬프트에서 javac를 하면 메시지가 나옵니다.
Note : UpDownCasting.java uses unchecked or unsafe operations.
Note : Recompile with -Xlint:unchecked for details.
그래서 javac -Xlint UpDownCasting.java 하면
UpDownCasting.java:13: warning: [unchecked] unchecked call to addElement(E) as a member of the raw type java.util.Vector
v.addElement(name);
UpDownCasting.java:14: warning: [unchecked] unchecked call to addElement(E) as a member of the raw type java.util.Vector
v.addElement(id);
김강욱님// '자바 클래스 패스가 없는 것'이 무슨 의미인지 모르겠습니다. 설명 부탁 드려도 될까요?
-
김강욱
06.29 19:57
자바 버전이 다른가 보군요.
java -version 을 각각 해보세욤~
-
해색주
06.29 21:20
김강욱님// Java 1.5부터는 Vector를 검사하는 부분이 있다고 하더군요. 결국 source 버전을 다르게 해서 compile 하면 되더군요.
http://blog.dreamwiz.com/ospace/4532214
-
가영아빠
06.29 21:21
그건 에러는 아니고요, 뭐라고 해야 할까요.
일단 Generic 이라는 것을 아셔야 합니다. Vector는 기존에는 Object 타입을 받아들였습니다.
그래서 이놈도 넣고 저놈도 넣고 했죠. 예를 들면 지금 소스에서 String도 넣으시고, Integer도 넣으셨네요.
한마디로 Object를 상속받는 것들은 다 집어넣을 수 있죠.
하지만, 1.5부터는 Generic이 도입되었습니다. 이는 C++의 Template의 다른 말과도 같습니다. 조금 다른 형제같은 개념입니다.
한마디로 Vector를 포함한 콜렉션클래스들에 Generic한 것들을 다 구현해 놓고, 특정 자료형에 맞춰서 쓸 수 있도록 한다는 개념입니다.
Vector<String> strings = new Vector<String>(); 과 같은 개념이죠.
그런데 이렇게 Generic 이 콜렉션에 도입되자 문제가 생겼습니다.
본문의 예제처럼 콜렉션에 이놈도 넣고 저놈도 넣고 할 수가 없어진 것이죠.
물론 기존과 호환을 위해서 non-standard 들도 쓸 수는 있습니다. 다만, warning을 주죠.
바로 그 워닝이 리플에 다신 그 워닝입니다. 한마디로 '너 콜렉션 쓰는데 왜 자료형 check안하고 쓰냐?' 이 말입니다.
본문의 예제도 non-standard에 대해서 warning을 준 것이지, error는 아닙니다.
여튼 컴파일에 워닝 뜨면 신경쓰이는 것은 정신 제대로 박힌 프로그래머라면 당연한 것이겠죠.
결국 불만이 나오게되고, 이런 불만이 접수되어서 1.6에서 Generic에 대해서 special annotation이 도입되었습니다.
@SuppressWarnings("unchecked") 를 이용하시면 non-standard에 대해서 warning을 주지 않는 것이죠
그래서 소스를
import java.util.Vector;
public class UpDownCasting {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
String name = new String("홍길동");
Integer id = new Integer(10000);Vector v = new Vector();
v.addElement(name);
v.addElement(id);
Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
String str = (String)obj1;
Integer num = (Integer)obj2;
System.out.println("이름: " + str + " 번호:" + num);
String str2 = (String)v.elementAt(0);
Integer num2 = (Integer)v.elementAt(1);
System.out.println("이름: " + str2 + " 번호:" + num2);
}
}과 같이 수정하시면 warning도 사라집니다.
그렇지만, 어느 책으로 공부하시는지, 누가 가르쳐 주시는지 모르겠지만, 구식입니다.
요즘 책에 저런 예제 나온다면 그건 진짜 정신 제대로 못 박힌채 책을 쓴 것입니다.
아니, 나올 수는 있지만 그러면서 generic에 대한 설명을 하지 않고, 콜렉션을 그냥 쓰고 있다면 그 책은 버리세요.
사람이 가르쳐 주고있다면, 다른 사람을 고르시고요.
왜 그러냐하면 non-standard입니다. 자바는 standard가 휙휙 변하는 언어입니다.C++의 0x가 결정되는데 수년이 넘게 걸렸지만, 자바는 그 것보다 매우 빠르게 변합니다. RPC같은 쪽은 아예 걔념 자체가 1.1 에서 1.2오면서 '헉' 하게 변하더니만 1.2에서 다시 1.4오면서 'ㅡ.ㅡ^' 하게 변했습니다.실제로 사용할때도, 이놈의 standard문제 때문에 JRE의 버전을 개발버전과 맞추는 경우도 많습니다.(최신이 1.6이더라도1.4로 개발하고 JRE에 1.4로 실행하라고 명시하는 것이죠)
그러니 배우는 중이시라면 항상 최신의 교재로 공부하시길 추천드립니다.
-
가영아빠
06.29 21:42
그러면 최대한 교과서 적인 예제로 변경해 보겠습니다.
package net.javaole.test;
import java.util.Vector;
public class UpDownCasting {
public static void main(String[] args) {
String name = new String("홍길동");
Integer id = new Integer(10000);Vector<Object> v = new Vector<Object>();
v.addElement(name);
v.addElement(id);
Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
String str = null;
Integer num = null;
if ( obj1 instanceof String ) {
str = (String)obj1;
}
if ( obj2 instanceof Integer ) {
num = (Integer)obj2;
}
System.out.println("이름: " + str + " 번호:" + num);
if (v.elementAt(0) instanceof String && v.elementAt(1) instanceof Integer) {
String str2 = (String)v.elementAt(0);
Integer num2 = (Integer)v.elementAt(1);
System.out.println("이름: " + str2 + " 번호:" + num2);
}
}
}빨간색 친 부분을 보시면, Vector를 generic을 이용해서 Vector<Object>로 초기화 해줬습니다.
이제 Object나 그것의 자식들은 다 들어갈 수 있겠죠. String Integer는 당연히 Object의 상속이니 OK 입니다.
이째 넣어놓은 것을 곶감 빼듯이 빼야 하는데요, 이때 당연하지만 자료형을 체크 해줘야 합니다. 실수로 Integer를 String으로 변경할 수도 있게 될 수 있잖습니까? 예를 들면 이런 것이죠.
Object obj1 = v.elementAt(0);
Object obj2 = v.elementAt(1);
String str = (String)obj2;
Integer num = (Integer)obj1;컴파일에서 에러는 없지만, Runtime exception이 발생하죠. 실수일 뿐인데요.
그래서 instanceof 를 이용해서 꼭 형변체크를 해줘야 합니다.
그러면
if ( obj1 instanceof String ) {
str = (Integer)obj1;
}
if ( obj2 instanceof Integer ) {
num = (String)obj2;
}와 같은 구문은 compile-time 에러체크가 됩니다. obj2가 Integer를 만족했는데 String으로 변환한다는 것은 명백한 실수죠.
(obj1도 마찬가지고요)
이 외에도 파고 들면 더 해야 하는 얘기들이 많지만요(intanceof를 최대한 줄여야 하는 이유 등등 뭐 그런 것들이요)
일단은 여기까지만 쓰겠습니다.
-
해색주
06.30 11:21
가영아빠님// 저는 소설같은 자바를 보고 있는데요, 산 지 몇 년이 되어서 버젼이 좀 낮을 겁니다. 일단 이책을 다보고 나서 다른 책을 구해보려구요. 자세한 답변 및 가르침 감사 드립니다. 나중에 다른 자바책 구하면 꼭 문의를 드려야겠어요.
-
가영아빠
06.30 13:29
해색주님// 음. 제가 1.2까지 자바 썼다가, 하는 수없이 작년 가을 부터 다시 공부했는데요.
평이 너무너무 좋아서 그 소설같은 자바의 최신판인 3판으로 공부했거든요.
그 책은 2일만에 다 보고 라면 받침으로 쓸까 잠깐 고려했습니다.
제가 리플에서 언급한 바꿔야 하는 것들의 범주에 해당된다고 자신있게 말할 수 있습니다. =_=
-
김강욱
06.30 16:13
언어가 괜히 더 어려워 진듯.
지금의 자바를 보고 있자면,
꼭 예전에 Structure 나 function pointer, pointer 의 pointer 를 이용하며, C ++ 의 객체 개념이 다 구현이 가능한데, 왜 이렇게 새로운 걸 자꾸 만드나...싶은 느낌이네요.
그래도 좋아지고 있는 거겠죠...ㅋㅋ
어떤 에러가 나시나요? jdb로 디버깅 해봤지만 특별히 에러나는 것 없던데요?