[ java ] in KIDS 글 쓴 이(By): hell (나누구야) 날 짜 (Date): 1997년10월09일(목) 21시54분04초 ROK 제 목(Title): 자바의 데이터형과 변수 (2) ------------------------------------------------------------------------------ 뉴스제공시각 : 02/01 00:00 출처 : 마이크로 제목 : 자바프로그래밍[2]/자바의 데이터형과 변수 (2) ----------------------------------------------------------------------------- 변수(variable) 지금까지 간단히 자바에서 제공되는 데이터형에 대해서 알아 보았다. C/C++ 등의 언 어에 익숙한 독자라면 당장에 자바가 '포인터형, 열거형(enum), 스트럭처(struct), 유 니온(union)' 등을 제공하지 않는다는 것을 발견했을 것이다. 뉴스그룹에서 아직도 일부 사람은 이러한 특징이 없어져 곤란하다는 호소를 하고 있다. 하지만 이런 변화 는 다음과 같은 면에서 자바가 더욱 쉽고 명료한 언어가 되는 데 기여하고 있다. 이 제 자바에서 변수를 선언하고 사용하는 방법에 대해 알아 보도록 하자. 변수의 이름 자바에서 변수 이름은 C/C++와 같이 철저하게 영어 대소문자를 구분한다. 또한 앞서 언급한 바와 같이 유니코드에서 글자(letter)로 인정하는 문자로 시작해서 두번째 글 자부터는 문자 혹은 숫자가 사용될 수 있다. 이 숫자도 단순히 아라비아 숫자뿐 아 니라 다양한 나라의 다양한 숫자가 사용될 수 있다. 예를 몇 개 들어보자. test I386 마소 ともだち // 맞는 예 char (형 이름) 3i (숫자가 앞일 수 없다) new.1 ('.'이 들어갔다) // 틀리는 예 형 이름 등 자바 언어에서 사용하기 위해 예약된 키워드(keyword)는 사용할 수 없 다는 점을 알아 두기 바란다. 참고로 변수 이름 외에도 클래스 이름이나 메쏘드 이 름 등 소위 말하는 '식별자(identifier)'를 만들 때는 변수 이름과 같은 규칙에 따라 이름을 붙여야 한다. 변수의 선언 변수는 어떤 특정한 형(type)의 데이터값을 가지고 있는 기억장소이다. 지난호에도 잠시 언급했지만 선언하는 위치와 방법에 따라 다른 성질을 가진다. 변수를 사용하 는 방법과 기억장소 관리 측면에서 간단히 분류하면 다음과 같다. 다음의 예제는 참 고자료④의 pp.49에서 발췌해 수정한 것이다. 완전히 동작하는 프로그램은 아니니까 컴파일을 시도하지는 말기 바란다. class Point { public static int numPoints; // 클래스 변수(class variable) public int x, y; // 인스턴스 변수(instance variable) public int[] properties = new int[10]; // properties[1] 같은 배열의 요소들 // properties는 참조형 변수이면서 배열을 가리키도록 초기화되었다. public int setX(int x) { // 메쏘드의 매개 변수 int oldX = this.x; // 지역 변수(local variable) this.x = x; } } ■ 클래스 변수 메쏘드에 속하지 않는 변수중 static을 붙여 선언한 것이다. 지난호의 예제에서 설명 했지만, 한 클래스에서 인스턴스(instance)가 여러 개 생성되더라도 단 하나만이 존 재한다. 위의 예에서 매번 Point 클래스의 인스턴스가 생성될 때마다 numPoints의 값을 증가시키면 Point 클래스를 기반으로 생성한 모든 Point 객체의 수를 유지할 수 있다. 이는 클래스 변수의 가장 대표적인 사용 예중 하나이다. ■ 인스턴스 변수 역시 지난호 예제를 참고하기 바란다. 인스턴스 변수는 생성된 객체마다 각기 변수 를 갖게 된다. 객체의 상태는 인스턴스 변수에 보존된다. 위의 예에서 각 Point 객체 는 x, y에 좌표라는 자신의 상태를 보존해 두고 있는 것이다. ■ 지역 변수 분류하기 나름이지만 여기서는 지역 변수에 메쏘드의 매개 변수 등을 함께 포함해 생각하기로 하자. 이 변수들은 메쏘드가 호출될 때 생성되는 프레임(frame)에 위치하 고 있다. 참고로, 프레임은 메쏘드가 호출될 때 그 메쏘드를 호출한 쓰레드의 스택 (stack)에 할당된다. C/C++에서와 같이 지역 변수는 메쏘드가 수행중인 동안만 존재 하며, 메쏘드에서 리턴(return)할 때 없어진다. 위의 예에서 보듯이 특정 데이터형의 변수를 선언하기 위해서는 C/C++에서와 같이 형 이름을 쓰고 다음에 변수의 이름을 써 주면 된다. C/C++를 배운 적이 있는 사람 이라면 포인터, 함수, 배열 등의 얽혀서 마치 암호같은 선언을 많이 접했을 것이다. 하지만 자바는 휠씬 간단하다. 포인터가 없다는 것이 가장 큰 이유일 것이다. C/C++ 에서 우리를 괴롭힌 것은 바로 포인터였다. char (*(*x[3])())[5]; 자바에선 위와 같이 복잡한 변수 선언은 더이상 없다. 이번에는 참조형에 대한 예제 를 살펴 보도록 하자. Point pt1 = new Point(); Point pt2 = pt1; pt은 Point 클래스에서 생성된 객체를 가리키는 참조형 변수이다. C++에 경험이 있 는 독자라면 의아해 할 것이다. C++에서는 다음과 같이 사용했기 때문이다. Point pt; Point* ppt = &pt; // 포인터 변수 Point& rpt = pt; // 참조형 변수 그러면 독자의 빠른 이해를 위해 자바와 C++ 경우의 차이점을 그림으로 표시해 보 자(<그림 1>). <그림 1> 자바와 C++의 참조형 변수 선언에 따른 차이점 사실 <그림 1>로 보기에는 별로 틀린 것이 없어 보인다. 하지만 사실상의 차이는 크 다. 자바에서는 객체 자체가 변수가 될 수 없다. 따라서 자바에서 객체는 항상 'new' 연산자를 통해 힙(heap)이라고 불리는 메모리 영역에서 동적으로 할당된다. C++의 예에서는 Point 객체가 pt라는 이름이 있고 지역 변수로 선언될 수도 있지만, 겉보기 에는 똑같이 선언된 자바의 pt1, pt2는 그 자체는 Point 클래스의 인스턴스를 가리 키는 일종의 포인터일 뿐이다. 단, 조심해야 할 것은 자바의 참조형을 내부적으로 메 모리의 어떤 장소를 가리키는 C/C++의 포인터와 동일하다고 생각해서는 안된다는 것이다. pt1, pt2와 같은 참조형은 실제 객체의 메모리 주소를 가지고 있는 배열의 인덱스(index)를 가질 수도 있다. 실제 썬의 JDK는 이와 같이 일종의 핸들(handle)을 갖도록 구현되어 있다. pt1.x = 1; 자바의 경우 위와 같이 객체의 인스턴스 변수에 접근할 수 있다는 것은 지난호에 이 미 설명했다. C++의 경우 참조형과 포인터형이 내부적으로는 동일하게 pt라는 이름 으로 할당된 Point 객체의 주소를 가리키지만 다음과 같이 접근하는 경우의 문법이 틀리다. ppt->x = 1; rpt.x = 1; pt.x = 1; 2번째와 3번째 줄에서 보듯이 참조형은 문법상 일반 객체 변수와 동일하게 사용된 다. C++에서는 참조형 변수는 반드시 선언할 때 초기화되어야 하지만, 자바의 참조 형은 어느 때고 포인터와 같이 값을 대입할 수 있다는 점을 유의하기 바란다. |