-
원시 변수와 레퍼런스Programming/JAVA 2010. 5. 3. 08:04
네 변수를 알라
변수는 크게 원시 변수와 레퍼런스, 이렇게 두 가지로 나눌 수 있습니다.
지금까지는 두가지 용도로 사용해 왔습니다.
하나는 객체 상태(인스턴스 변수)였고 다른 하나는 지역 변수(메소드 안에서 정의된 변수) 였지요.
변수는 원시 변수와 객체 레퍼런스로 나눌수 있습니다.
원시 변수에는 정수, 부울, 부동소수점 수와 같은 기초적인 값이 들어갑니다.
객체 레퍼런스에는 객체에 대한 레퍼런스가 들어갑니다.
- 변수에는 유형이 있어야 합니다.
- 변수에는 이름이 있어야 합니다.
int (유형) count; (이름)
키워드와 변수명.
- 반드시 알파벳 글자, 및줄(_) 또는 달러 기호($)로 시작해야 합니다. 숫자로 시작은 안되요.
- 두 번째 문자부터는 숫자도 쓸 수 있습니다. 숫자로 시작 하지만 않으면 괜찮습니다.
- 위의 두 가지 규칙을 지키고 자바 예약어만 사용하지 않는다면 어떤 이름이 든지 마음대로 사용할 수 있습니다.
- 여덟 가지 원시 유형은 다음과 같습니다.
- boolean char byte short int long float double
객체를 제어하는 방법
객체 변수라는 것은 없습니다.
객체 레퍼런스 변수라는 것만 있지요.
객체 레퍼런스에는 객체에 접근하는 방법을 알려주는 비트가 들어있습니다.
객체 레퍼런스에 객체 자체가 들어있는 것은 아닙니다. 포인터 같은 것이 들어있을 뿐이죠.
아니면 주소가 들어있다고 봐도 됩니다. 하지만 자바에서는 레퍼런스 변수 안에 무엇이 들어있는지 알 수 없습니다. 그렇지만 그 안에 무엇이 들어있든지 상관없이 그 레퍼런스가 객체 단 하나를
가리킨다는 것은 확실합니다. 그리고 JVM 은 레퍼런스를 사용하여 객체를 다루는 방법을 알고 있습니다.
리모컨 버튼이라고 생각하세요.
Dog d = new Dog();
d.bark();
Dog레퍼런스 변수는 Dog에 대한 리모컨이라고 생각해 보세요.
이 리모컨을 가지고 해당 객체에 어떤 일을 지시할수 있습니다.(메서드 호출.)
객체 레퍼런스는 단지 또 다른 변수 값에 불과 합니다.
즉, 컵에 들어가는 것이라고 보면 됩니다. 단지 이번에는 그 컵 안에 리모컨이 들어간다고 볼 수 있는 것이죠.
객체 선언, 생성과 대입의 3단계
Dog myDog = new Dog();
1. 레퍼런스 변수 선언
Dog myDog
2. 객체 생성
new Dog();
3. 객체와 레퍼런스 연결
Dog myDog = new Dog();
가비지 컬렉션 기능이 있는 힙에서의 삶
힙에서의 삶과 죽음
배열은 찬장의 컵과 같습니다.
-
int 배열 변수를 선언합니다. 배열 변수는 배열 객체에 대한 리모컨입니다.
int[] nums;
-
길이가 7인 새로운 int 배열을 생성하고 앞에서 만든 nums라는 int[] 변수에 대입합니다.
nums = new int[7] ;
-
배열의 각 원소에 int값을 대입합니다.
int 배열에 있는 원소는 int 변수일 뿐이라는 점 기억하세요.
nums[0] = 1; nums[1] = 2; nums[2] = 3; nums[3] = 4; nums[4] = 5; nums[5] = 6; nums[6] = 7;
※ 배열은 원시 변수의 배열이든 객체 레퍼런스에 대한 배열이든 상관없이 항상 객체입니다.
Dog배열을 만들어 봅시다.
-
Dog 배열 변수를 선언합니다.
Dog[] pets;
-
길이가 7인 Dog배열을 만들어서 앞서 선언한 Dog[]변수인 pets에 대입합니다.
pets = new Dog[7];
현재 Dog객체는 없습니다. Dog레퍼런스에 대한 배열을 만들긴 했지만 실제 Dog객체는 아직 하나도 없습니다.
-
새로운 Dog객체를 생성하고 그 객체를 배열 원소에 대입합니다.
Dog배열에 들어있는 원소는 Dog레퍼런스 변수에 불과하다는 점을 잊지마세요. Dog객체는 따로 만들어야합니다.
pets[0] = new Dog(); pets[1] = new Dog();
Dog를 제어해 봅시다.(레퍼런스 변수를 사용합니다.)
Dog fido = new Dog(); Dog객체를 만들고 fido라는 레퍼런스 변수에 대해 점 연산자를 사용하여 name변수에 접근했습니다.
fido.name ="Fido"; fido레퍼런스를 사용하여 개가 짖거나 먹거나 고양이를 쫓아가도록 할 수 있습니다.
fido.bark();
fido.chaseCat();
Dog가 Dog배열에 들어있으면 어떻게 될까요?
Dog[] myDog = new Dog[3]; 점 연산자를 이용하면 Dog의 인스턴스 변수나 메소드에 접근할 수 있어요.
myDog[0] = new Dog(); Dog가 배열에 들어있을 때는 실제 변수명이 없죠. 대신 배열 표기법을 이용하여 배열의 특정 인덱스에 객체를 잡아 넣을 수 있습니다.
myDog[0].name = "Fido";
myDog[0].bark();
자바에서는 유형을 철저하게 따진다??
일단 배열을 선언하고 나면 선언할 때 지정한 배열의 유형에 속하는 것을 제외하고 다른 것은 절대 집어넣을 수 없습니다.
예를 들어, Dog배열에 Cat을 집어넣을수 없죠.
마찬가지로 int 배열에 double를 집어넣을 수는 없겠죠??
하지만 byte는 언제나 int 크기의 컵에 들어갈수 있으니까 byte를 int배열에 집어넣을 수는 있습니다.
이런것을 암묵적인 확대(implicit widening) 라고 합니다.
일단 지금은 배열을 선언할 때 지정한 유형이 아닌 다른 유형을 넣으려고 하면 컴파일러에서 오류를 발 생시킨다는 점. 기억하세요.
Dog 예제
class Dog{
String name;
public static void main(String[] args) {
Dog dog1 = new Dog();
dog1.bark();
dog1.name='Bart';
Dog[] myDogs = new Dog[3];
myDog
}
}
핵심정리
- 변수에는 원시 변수와 레퍼런스, 이렇게 두 종류가 있습니다.
- 변수를 선언할 때는 반드시 이름과 유형이 있어야 합니다.
- 원시 변수의 값은 그 값을 표시하는 비트로 구성됩니다. (5,'a',true,3.1416 등등)
- 레퍼런스 변수의 값은 힙에 들어있는 객체를 건드릴 수 있는 방법을 나타내는 비트입니다
- 레퍼런스 변수는 리모컨과 같습니다. 레퍼런스 변수에 대해 점(.)연산자를 사용하는 것은 리모컨의 버튼을 눌러서 메소드나 인스턴스 변수에 접근하는 것과 비슷합니다.
- 레퍼런스 변수가 아무 객체도 참조하지 않으면 그 값은 null이 됩니다.
- 배열은 항상 객체 입니다. 배열에 원시 변수를 저장하도록 선언해도 마찬하기죠. 원시 배열 같은 것은 없습니다. 원시 변수가 들어있는 배열이 있을 뿐입니다.
'Programming > JAVA' 카테고리의 다른 글
JDBC API 를 이용한 프로그래밍. (0) 2010.05.03 클래스와 객체 (0) 2010.05.03 자바를 소개합니다. ^^ (0) 2010.05.03 메소드를 더 강력하게 (0) 2010.05.03 객체의 행동 (0) 2010.05.03