728x90
1. 변수선언
- 자바는 유형(type)을 철저하게 따진다.
- 변수에는 크게 원시 변수(primitive variable), 객체레퍼런스(objectreference) 두 가지로 나눌 수 있다.
- 변수에는 유형이 있어야 한다.
- 변수에는 이름이 있어야 한다.
- 뭔가를 담아두기 위한 용도로 쓰인다.
1) 원시 변수
- 정수, 부울, 부동소수점 수와 같은 기초적인 값(단순한 비트 패턴으로 나타낼 수 있는 값)
유형 |
비트 수 |
범위 |
부울과 문자 | ||
boolean |
|
true 또는 false |
char |
16비트 |
0~65535 |
정수 | ||
byte |
8비트 |
-128~127 |
short |
16비트 |
-32768~32767 |
int |
32비트 |
-2147483648~2147483647 |
long |
64비트 |
-아주 큰 값~아주 큰 값 |
부동소수점 소수 | ||
float |
32비트 |
바뀔 수 있음 |
double |
64비트 |
바뀔 수 있음 |
ex) 커피전문점에 long, int, short, byte란 이름을 가진 컵들이 있다. 원시 변수로 주문을 한다고 하면 "int(유형) 하나만 주세요. 값은 2486(변수에 들어갈 값)으로 하고 변수 이름은 height(변수 이름)로 해 주세요"
- int 변수를 byte 변수에 대입하려고 하면 컴파일 되지 않는다. byte는 8비트의 변수이고, int는 32비트 변수 이다. 그러나 byte 변수를 int에 대입은 가능하다.
ex) int 컵을 byte 컵에 넣을 순 없다. 반대의 경우에는 가능. 이런 것을 암묵적인 확대(implicit widening)라고 한다.
변수명
- 반드시 알파벳 글자, 밑줄(_) 또는 달러 기호($)로 시작해야 한다. 숫자로 시작하면 안된다.
- 두 번째 문자부터는 숫자도 쓸 수 있다. 숫자로 시작하지 않으면 괜찮다.
- 위의 두가지 규칙을 지키고 자바 예약어만 사용하지 않는다면 어떤 이름이든지 마음대로 사용할 수 있다.
키워드
- 컴파일러에서 인식할 수 있는 키워드(keyword)를 비롯한 단어들이 바로 예약어(reserved word)이다.
- 원시 변수 유형도 예약어에 속한다.
2) 객체
- 객체 변수라는 것은 없다.
- 객체 레퍼런스 변수라는 것만 있다.
- 객체 레퍼런스에는 객체에 접근하는 방법을 알려주는 비트가 들어있다.
- 객체 레퍼런스에 객체 자체가 들어있는 것은 아니다. 포인터 같은 것이 들어 있다. 아니면 주소가 들어있다고 봐도 된다. 하지만 자바에서는 레퍼런스 변수 안에 무엇이 들어 있는지 알 수 없다. 그렇지만 그 안에 무엇이 들어있든지 상관없이 그 레퍼런스가 객체 단 하나를 가리킨다는 것은 확실하다. 그리고 JVM은 레퍼런스를 사용하여 객체를 다루는 방법을 알고 있다.
- 객체를 변수에 넣을 수 없다.
- 객체는 가비지 컬렉션 기능이 있는 힙에서만 산다.
- "점 앞에 것을 이용해서 점 뒤에 있는 것을 주세요"라고 이해
ex) myDog.bark();
"myDog라는 변수로 참조할 수 있는 객체를 이용하여 bark() 메소드를 호출하라"를 의미
- 객체 레퍼런스는 단지 또 다른 변수 값에 불과하다.
객체 선언, 생성과 대입의 3단계
Dog myDog = new Dog()라는 구문에서
① 레퍼런스 변수 선언
Dog myDog
jvm에 레퍼런스 변수용 공간을 할당해 달라는 요청을 한 다음 그 변수명을 myDog로 지정한다. 이렇게 하면 myDog라는 레퍼런스 변수는 영원히 Dog 유형의 변수가 된다.
다른 유형의 레퍼런스 변수와는 절대 사용할 수 없다.
② 객체 생성
new Dog();
jvm으로 하여금 힙에 새로운 Dog 객체를 위한 공간을 마련하도록 지시한다.
③ 객체와 레퍼런스 연결
=
새로운 Dog 객체를 myDog라는 레퍼런스 변수에 대입한다.
힙( heap)이란?
원시 자료형이 아닌 보다 큰 크기의 데이터를 담고자 동적으로 할당하는 메모리 공간이다.
실행 시간에 크기가 결정되는 동적 배열 및 리스트와 같은 경우 힙을 사용하는 것이 보다 공간을 효율적으로 활용할 수 있다.
c언어와 같은 경우 사용한 공간을 명시적으로 반환해 주어야 하므로 이 과정을 빠뜨림으로서 메모리 누수와 같은 버그의 원이이 되기도 한다.
* 자세한 내용은 아래 사이트들 참고
http://ko.wikipedia.org/wiki/%ED%9E%99_%28%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%29 (프로그래밍에서의 힙)
http://ko.wikipedia.org/wiki/%ED%9E%99_%28%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0%29 (자료구조에서의 힙)
http://blog.naver.com/jkb8245/17627649
final인 경우 Dog 객체 하나가 대입되었다면 바로 그 Dog 객체가 아닌 다른 Dog 객체를 참조 할 수 없다.
Dog 객체 하나를 참조하다가 다른 Dog 객체를 참조하는 것도 가능하고, null 값이 있을 수도 있다.
가비지 컬렉션 기능이 있는 힙에서의 삶
Book b = new Book();
Book c = new Book();
--> Book 레퍼런스 두 개를 선언. Book 객체 두 개를 생성. 생성한 Book 객체를 레퍼런스 변수에 대입. Book 객체 두 개는 힙에서 살고 있다.
레퍼런스 2개, 객체 2개
Book d = c;
--> 새로운 Book 레퍼런스 변수를 선언. 세번째 Book 객체를 새로 생성하는 대신 c라는 변수에 들어있는 값을 d라는 변수에 대입.
'c에 들어 있는 비트들을 꺼내서 복사한 다음 그 복사본을 d에 집어 넣어라'로 이해
c와 d는 똑같은 객체를 참조
c와 d 변수에는 같은 값의 서로 다른 복사본 두 개가 들어 있다.
레퍼런스 3개, 객체 2개
c = b;
--> 변수 b의 값을 변수 c에 대입.
'b에 들어 있는 비트들을 복사해서 새로운 복사본을 c변수에 넣어라'로 이해
b와 c는 모두 같은 객체를 참조
레퍼런스 3개, 객체 2개
힙에서의 삶과 죽음
Book b = new Book();
Book c = new Book();
--> Book 레퍼런스 변수 두 개를 선언. Book 객체 두 개를 새로 생성합니다. 그리고 Book 객체를 레퍼런스에 대입. Book 객체 두 개가 힙에서 살게 됨.
활성 레퍼런스 2개, 접근 할 수 있는 객체 2개
b = c;
--> c의 값을 b에 대입. c에 들어있는 비트를 복사한 다음 새로운 복사본을 b 변수에 집어 넣는다. 이제 두 변수는 똑같은 값이 들어 있다.
b와 c는 모두 같은 객체를 참조. 1번 객체는 버림 받았기 때문에 가비지 컬렉션(GC, Garbage Collection) 대상.
활성 레퍼런스 2개, 접근할 수 있는 객체 1개, 버림받은 객체 1개
처음 b로 참조했던 1번 객체는 더 이상 아무 레퍼런스도 남아 있지 않음. 따라서 접근 할 수 없다.
c = null;
c 변수에 null 값을 대입. c가 null레퍼런스가 됨. 어떤 것도 참조하지 않음. c는 여전히 레퍼런스 변수고 나중에 대란 Book 객체를 c에 대입할 수 있다.
2번 객체에는 여전히 활성 레퍼런스(b)가 있고, 활성 레퍼런스가 있는 한 GC 대상이 되지 않음.
활성 레퍼런스 1개, null 레퍼런스 1개, 접근할 수 있는 객체 1개, 버림받은 객체 1개
* 객체는 가비지 컬렉션 기능이 있는 힙 안에서 삶
배열은 찬장의 컵과 같다.
배열도 객체이다.
- 자바 표준 라이브러리에는 맵(map), 트리(tree), 집합(set)을 비롯한 여러가지 복잡한 자료 구조(data structure)가 있다. 하지만 사물의 순서가 있는, 그리고 효율적인 목록을 빠르게 만들 때 배열을 쓰는 것이 좋다.
- 배열을 사용하면 인덱스 위치를 써서 배열에 있는 임의 원소를 사용할 수 있기 때문에 올바른 임의 접근이 가능
- 배열의 모든 원소는 그냥 변수
- 배열은 원시 변수의 배열이든 객체 레퍼런스의 배열이든 상관없이 항상 배열이다.
Dog 배열을 만들어 봅시다.
Dog [] pets;
--> Dog 배열 변수를 선언
pets = new Dog[7]
--> 길이가 7인 Dog 배열을 만들어서 앞서 선언한 Dog[] 변수인 pets에 대입
pets[0] = new Dog();
pets[1] = new Dog();
--> 새로운 Dog 객체를 생성하고 그 객체를 배열 원소에 대입. Dog 배열에 들어있는 원소는 Dog 레퍼런스 변수에 불과하다는 점. Dog 객체는 따로 만들어야 한다!!
Dog를 레퍼런스 변수를 사용하여 제어
Dog fido = new Dog();
fido.name = "Fido";
fido.bark();
fido.chaseCat();
Dog를 배열에 있는 경우
Dog [] myDogs = new Dog[3];
myDog[0] = new Dog();
myDog[0],name = "Fido";
myDog[0].bark();
728x90
'개발및업무 > JAVA' 카테고리의 다른 글
[Head First Java] 2. 객체 마을로의 여행 (0) | 2011.11.06 |
---|---|
[Head First Java] 1. 껍질을 깨고 (0) | 2011.11.02 |
HashMap, TreeMap, Hashtable 사용법 정리 (0) | 2011.09.14 |
초성조회 (0) | 2011.09.05 |
JDBC 사용을 위한 CLASSPATH 설정하기 (0) | 2011.07.11 |