자바 문제
조회수 1422회
오류를 모두 찾고 수정하시오.
1) Calendar d = new Calendar();
2) int i = new Integer(0);
3) Integer i = new Integer("100");
4) int i = Integer.parseInt("100");
5) String s = new String("abc");
라는 문제인데요. 답지가 없어서 올리게 되었습니다 ㅠㅠㅠ 1)번을 제외하고 나머지는 프로그램을 돌리니깐 모두 값이 나오더라구요. 근데 제 생각에는 3번도 문제가 있는 것처럼 보이거든요..ㅠㅠㅠ
어떤부분이 오류이고 왜 그런지 친절하게 설명해주실 분 계시나요?
2 답변
-
Calendar d = new Calendar(); // Cannot instantiate the type Calendarjava.util.Calendar 클래스는 (JDK10 기준) 생성자가 두 개가 있는데요. 둘 모두 protected 접근 제어자가 선언되어 있습니다. https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html#%3Cinit%3E()protected는 같은 패키지에 있거나 Calendar 클래스를 확장(=상속)한 클래스만 접근 가능합니다. 이 때문에 컴파일 에러가 발생하니 오류라고 하는거죠.보통은
Calendar
타입의 인스턴트를 만들때java.util.GregorianCalendar
를 사용합니다:import java.util.GregorianCalendar; // 생략 Calendar a = new GregorianCalendar();
그런데, 3번은 어떤게 문제라고 생각하세요?
- 제가 막 자바를 배우는 단계라... int랑 Integer랑 다르다는 건 알고 있는데 Integer가 정수를 받아야하니깐 "100"은 문자열이니 오류라고 생각을 했어요.... 궁금이 2018.10.24 10:45
- 다시 보니 틀린 답변이라서 수정했습니다. (부끄) 편집요청빌런 2018.10.24 11:19
- Integer의 생성자 메서드 중에 String을 받아서 int로 변환하는게 있어요. 따라서 new Interger(100), new Interger("100") 둘 다 맞습니다. 편집요청빌런 2018.10.24 11:24
- 아하 그렇군요! 감사합니다!:) 궁금이 2018.10.24 11:28
-
1) Calendar d = new Calendar();
2) int i = new Integer(0);
3) Integer i = new Integer("100");
4) int i = Integer.parseInt("100");
5) String s = new String("abc");
위의 항목 모두 설명이 필요해 보입니다.
물론 "오류"라고 할만한 것은 1번입니다.
1번 의 Calendar 클래스는 아래와 같습니다.
public abstract class Calendar extends Object implements Serializable, Cloneable, Comparable<Calendar>
추상클래스입니다. 당연히 new 연산자로 객체를 생성할 수 없습니다.
명백한 오류입니다.
2번의 경우는 new Integer(0) 해서 힙에 생성후 그걸 다시 언박싱하여 스택에 넣고 있는 형태입니다. jdk 1.5부터 오토 박싱, 언박싱이 되므로 오류는 아니나 비효율적인 형태입니다.
그냥 int i = 0 하면 됩니다.
3번의 경우는 한가지 생각해볼 것이 있습니다. 자바는 모두 타입이 객체가 아닙니다. 객체가 아닌 대표적인 것이 피리미티브형인 int, char, long, byte 이런 형태입니다. 객체가 아니니 heap 에 저장되지 않고 스택에 저장됩니다.
그럼 int, char 는 객체처럼 쓸 수 없나요? 그때 사용할 수 있는 것이 Integer 클래스입니다. new Integer() 하면 heap에 저장되고 가비지컬렉션 대상이 됩니다. int 는 스택에 저장되므로 기본적으로 가비지 컬렉션 대상이 아닙니다. 메소드 호출이 끝나면 자동 처리가 됩니다.
4번의 경우 new Integer 해서 heap 에 저장한 객체를 다시 프리니티브 타입으로 변경(언박싱)해서 stack 에 넣는겁니다. 그냥 비효율적인 형태입니다만 필요한 경우가 많습니다. 예를들어 ArrayList 에 int 들을 담는다고 생각해보죠.
ArrayList 는 객체만 담을 수 있습니다. int 는 담을 수 없죠. 그때 new Integer(1) 이런식으로 객체형으로 만들고 담습니다. 당연히 ArrayList 에서 값을 받아오면 객체이므로 언박싱을 통해 int 로 변환해야 합니다.
5번의 경우는 jvm constants pool 이라는 개념과 intern 개념을 알아야 합니다. 쉽게 말하면
String a = "abcd"; String b = "abcd"; String A = new String("abcd"); String B = new String("abcd");
상기 두개의 a, b 는 같습니다만 A, B는 다릅니다.
문자열은 상수이며 문자열만 저장되는 공간이 별도로 있기 때문에 가능한 일입니다. 그러나 new String 하면 heap에 저장되므로 불필요한 낭비를 하게 됩니다.
댓글 입력