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

+ Recent posts