5.1 데이터 타입(Data Type) 분류
분류 | 종류 | |
기본 타입 (primitive type) |
정수 타입 | byte, char, short, int, long |
실수 타입 | float, double | |
논리 타입 | booean | |
참조 타입 (reference type) |
배열 타입 열거 타입 클래스 인터페이스 |
객체란?
데이터와 메소드로 구성된 덩어리. 미리 만들어진 프로그램 덩어리.
객체 = 데이터(필드) + 메소드
두 데이터 타입의 변수들은 모두 스택(stack)이라는 메모리 영역에 생성되는데, 기본 타입으로 선언된 변수는 값 자체를 저장하지만, 참조 타입으로 선언된 변수는 힙(heap)에 생성된 객체의 생성된 메모리 번지를 저장한다.
5.2 메모리 사용 영역
java 명령어로 JVM이 구동되면(java 명령을 실행하면) JVM은 운영체제에서 할당받은 메모리 영역(Runtime Data Area, RDA)을 구분해서 사용한다.
* JVM: Java Virtual Machine(자바 가상 머신)의 약자, 자바 프로그램을 실행하기 위해 필요한 가상화된 실행 환경
* RDA: 프로그램이 실행할 때 운영체제가 허용하는 메모리
메소드(Method) 영역
- 바이트 코드의 파일을 읽은 내용이 저장되는 영역.
- 클래스별로 상수, 정적 필드, 메소드 코드, 생성자 코드 등이 저장된다.
힙(Heap) 영역
- 객체가 생성되는 영역.
- 객체의 번지는 메소드 영역과 스택 영역의 상수와 변수에서 참조할 수 있다.
스택(Stack) 영역
- 메소드를 호출할 때마다 생성되는 프레임(Frame)이 저장되는 영역.
- 메소드 호출이 끝나면 프레임은 자동 제거된다.
- 프레임 내부에 있는 로컬 변수 스택에서 기본 타입 변수와 참조 타입 변수가 생성되고 제거(반납)된다.
5.3 참조 타입 변수의 ==, != 연산
==, != 연산자는 변수의 값이 같은지, 아닌지를 조사한다. 참조 타입 변수의 값은 객체의 번지이므로 참조 타입 변수의 ==, != 연산자는 번지를 비교하는 것이 된다. 번지가 같다면 동일한 객체를, 다르다면 다른 객체를 참조하는 것이다.
// B에 있는 주소값을 A에 대입한다.
A = B;
// A와 B의 주소값을 비교한다.
A == B;
A != B;
// 배열 변수 선언
int[] arr1;
int[] arr2;
int[] arr3;
arr1 = new int[] { ··· } // 배열 생성 후 변수에 대입
arr2 = new int[] { ··· } // 배열 생성 후 변수에 대입
arr3 = arr2; // // 배열 변수의 값 대입
5.4 nul과 NullPoinerException
참조 타입 변수는 아직 번지를 저장하고 있지 않다는 뜻으로 null(널) 값을 가질 수 있다. null도 초기값으로 사용할 수 있기 때문에 null로 초기화된 참조 변수는 스택 영역에 생성된다.
String refVar1 = "자바";
String refVar2 = null;
자바는 프로그램 실행 도중에 발생하는 오류를 예외(Exception)라고 부른다. 참조 변수를 사용하면서 가장 많이 발생하는 예외 중 하나는 NullPointerException이다.
5.5 문자열(String) 타입
자바의 문자열은 String 객체로 생성된다. String 변수를 선언하고 문자열 리터럴이 대입되면 문자열은 String 객체로 생성되고, 객체의 번지가 각각 대입된다.
문자열 비교
자바는 문자열 리터럴이 동일하다면 String 객체를 공유하도록 설계되어 있다. 각각의 문자열 변수에 서로 다른 값이 대입되어 있을 경우 동일한 String 객체의 번지가 저장된다. 각각의 문자열 변수에 new 연산자로 새로운 객체를 만들어서 각 문자열 변수에 대입한다면 서로 다른 String 객체의 번지를 가지게 된다. 그렇기 때문에 문자 리터럴로 생성하느냐 new 연산자로 생성하느냐에 따라 비교 연산자의 결과가 달라질 수 있다.
* new 연산자: 새로운 객체를 만드는 연산자. 객체 생성 연산자라고 한다.
String name1 = "홍길동";
String name2 = "홍길동";
String name1 = new String("홍길동");
String name2 = new String("홍길동");
문자 추출
문자열에서 특정 위치의 문자를 얻고 싶다면 charAt() 메소드를 이용할 수 있다. charAt() 메소드는 매개값으로 주어진 인덱스의 문자를 리턴한다.
* 인덱스: 0에서부터 '문자열의 길이-1'까지의 번호.
String subject = "자바 프로그래밍";
char charValue = subject.charAt(3);
System.out.println(charValue); // '프' 출쳑
문자열 길이
문자열에서 문자의 개수를 얻고 싶다면 length() 메소드를 사용한다. 변수 객체의 문자열 길이는 공백을 포함한다.
String subject = "자바 프로그래밍";
int intValue = subject.length(); // 총 8문자
문자열 대체
문자열에서 특정 문자열을 다른 문자열로 대체하고 싶다면 replace() 메소드를 사용한다. replace() 메소드는 기존 문자열은 그대로 두고 대체한 새로운 문자열을 리턴한다.
String oldStr = "자바 프로그래밍";
String newStr = oldStr.replace("자바", "JAVA");
String 객체의 문자열은 변경이 불가한 특성을 갖기 때문에 replace() 메소드가 리턴하는 문자열은 원래 문자열의 수정본이 아니라 완전히 새로운 문자열이다. 따라서 newStr 변수는 새로 생성된 문자열을 참조한다.
문자열 잘라내기
문자열에서 특정 위치의 문자열을 잘라내엇 가져오고 싶다면 substring() 메소드를 사용한다.
메소드 | 설명 |
substring(int begintIndex) | beginIndex에서 끝까지 잘라내기 |
substring(int beginIndex, int endIndex) | beginIndex에서 endIndex 앞까지 잘라내기 |
문자열 찾기
문자열에서 특정 문자열의 위치를 찾고자 할 때에는 indexOf() 메소드를 사용한다. indexOf() 메소드는 주어진 문자열이 시작되는 인덱스를 리턴한다. 만약 주어진 문자열이 포함되어 있지 않으면 indexOf() 메소드는 -1을 리턴한다.
String subject = "자바 프로그래밍";
int index = subject.indexOf("프로그래밍"); // 3 저장
System.out.println(index); // 3 출쳑
주어진 문자열이 단순히 포함되어 있는지만 조사하고 싶다면 contains() 메소드를 사용하면 편리하다. 원하는 문자열이 포함되어 있으면 contains() 메소드는 true를 리턴하고, 그렇지 않으면 false를 리턴한다.
문자열 분리
문자열이 구분자를 사용하여 여러 개의 문자열로 구성되어 있을 경우, 이를 따로 분리해서 얻고 싶다면 split() 메소드를 사용한다.
String board = "번호,제목,내용,성명";
String arr = board.split(",");
5.6 배열(Array) 타입
변수는 하나의 값만 저장할 수 있어서 저장해야 할 값의 수가 많아지면 그만큼 많은 변수가 필요하다. 이와 같은 방법은 매우 비효율적인 코딩이 된다. 따라서 많은 양의 값을 다루는 좀 더 효율적인 방법인 배열을 사용한다. 배열은 연속된 공간에 값을 나열시키고, 각 값에 인덱스(index)를 부여해 놓은 자료구조이다.
배열은 다음과 같은 특징을 가지고 있다.
- 배열은 같은 타입의 값만 관리한다.
- 배열의 길이는 늘리거나 줄일 수 없다.
배열 변수 선언
배열 변수 선언은 다음과 같이 두 가지 형태로 작성할 수 있지만, 관례적으로 첫 번째 방법을 주로 사용한다.
타입[] 변수;
타입 변수[];
배열 변수는 참조 변수이다. 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 주소를 저장한다. 참조할 배열이 없다면 배열 변수도 null로 초기화할 수 있다.
타입[] 변수 = null;
만약 배열 변수가 null 값을 가지 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생한다.
값 목록으로 배열 생성
배열에 저장될 값의 목록이 있다면, 다음과 같이 간단하게 배열을 생성할 수 있다.
타입[] 변수 = { 값0, 값1, 값2, 값3, ··· };
중괄호 { }는 나열된 값들을 항목으로 가지는 배열을 힙에 생성하고, 번지를 리턴한다. 배열 변수는 리턴된 번지를 저장함으로써 참조가 이루어진다.
중괄호 { }로 감싼 값의 목록을 배열 변수에 대입할 때 주의할 점이 있다. 배열 변수를 미리 선언한 후 값 목록을 변수에 대입할 수 없다. 배열 변수를 선언한 시점과 값 목록이 대입되는 시점이 다르다면 다음과 같이 작성하면 된다. 타입은 배열변수를 선언할 때 사용한 타입과 동일하게 주면 된다.
변수 = new 타입[] { 값0, 값1, 값3, ··· }
new 연산자로 배열 생성
값의 목록은 없지만 향후 값들을 저장할 목적으로 배열을 미리 생성할 수 있다. 다음과 같이 사용하면 배열 객체를 생성시킨다. 길이는 배열이 저장할 수 있는 항목 수를 말한다.
타입[] 변수 = new 타입[길이];
new 연산자는 해당 길이의 배열을 생성하고 배열의 번지를 리턴하기 때문에 배열 변수에 대입할 수 있다. 이미 배열 변수가 선언된 후에도 다음과 같이 대입이 가능하다.
타입[] 변수 = null;
변수 = new 타입[길이];
new 연산자로 배열을 처음 생성하면 배열 항목은 기본값으로 초기화된다.
데이터 타입 | 초기값 | |
기본 타입 | byte[ ] char[ ] short[ ] int[ ] long[ ] |
0 '\u0000' 0 0 0L |
float[ ] double[ ] |
0.0F 0.0 |
|
boolean[ ] | false | |
참조 타입 | 클래스[ ] 인터페이스[ ] |
null null |
배열을 생성하고 난 후 특정 인덱스 항목을 새로운 값으로 변경하는 방법은 동일하다.
변수[인덱스] = 값;
배열 길이
배열의 길이란 배열에 저장할 수 있는 항목 수를 말한다. 코드에서 배열의 길이를 얻으려면 도트(.) 연산자를 사용해서 참조하는 배열의 length 필드를 읽으면 된다. 배열의 length 필드는 읽기만 가능하므로 값을 변경할 수 없다.
배열변수.length;
배열 길이 필드를 for 문의 조건식에서 사용할 때 조심해야 한다. 배열의 마지막 인덱스는 배열 길이보다 1이 적기 때문에 해당 배열 안의 값을 사용하려면 <= 연산자 대신 < 연산자를 사용해야 한다.
5.7 다차원 배열
배열 항목에는 또 다른 배열이 대입될 수 있는데, 이러한 배열을 다차원 배열이라고 부른다.
다치원 배열에서 각 차원의 항목에 접근하는 방법은 다음과 같다.
변수[1차원인덱스][2차원인덱스]···[N차원인덱스]
값 목록으로 다차원 배열 생성
값 몰곡으로 다차원 배열을 생성하려면 변수 선언 시 타입 뒤에 대괄호 [ ]를 차원의 수만큼 붙이고, 값 목록도 차원의 수만큼 중괄호를 중첩시킨다.
// 2차원 배열 생성 후 대입
타입[][] 변수 = {
// 1차원 배열의 0 인덱스
// 10번지에 저장
{ 값1, 값2, ··· },
// 2차원 배열의 1 인덱스
// 30번지에 저장
{ 값3, 값4, ··· },
···
};
new 연산자로 다차원 배열 생성
new 연산자로 다차원 배열을 생성하려면 배열 변수 선언 시 타입 뒤에 대괄호 [ ]를 차원의 수만큼 붙이고, new 타입 뒤에도 차원의 수만큼 대괄호 [ ]를 작성하면 된다. 마지막 차원의 항목의 값은 초기값을 가진다.
// 2차원 배열 생성 후 대입
타입[][] 벼눗 = new 타입[1차원수][2차원수];
5.8 객체를 참조하는 배열
참조 타입(클래스, 인터페이스) 배열은 각 항목에 객체의 번지를 저장한다.
5.9 배열 복사
배열은 한 번 생성하면 길이를 변경할 수 없다. 더 많은 저장 공간이 필요하다면 더 큰 길이의 배열을 새로 만들고 이전 배열로부터 더 많은 항목들을 복사해야 한다.
가장 기본적인 복사 방법은 for 문을 이용해서 항목을 하나씩 읽고 새로운 배열에 저장하는 것이다. 배열 복사를 위한 좀 더 간단한 방법은 System의 arraycopy() 메소드를 이용하는 것이다.
System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
- src: 원본 배열
- srcPos: 원본 배열 복사 시작 인덱스
- dest: 새 배열
- destPos: 새 배열 붙여넣기 시작 인덱스
- length: 복사 항목 수
5.10 배열 항목 반복을 위한 향상된 for 문
카운터 변수와 증감식을 사용하지 않고, 항목의 개수만큼 반복한 후 자동으로 for 문을 빠져나간다.
5.11 main() 메소드의 String[] 매개변수 용도
자바 프로그램을 실행하기 위한 main() 메소드에 'String[] args'가 있다. 프로그램을 실행할 때 값을 요구할 수 있다. 그 값을 문자열로 취급하여 String[] 배열의 항목값으로 구성한 후 main() 메소드 호출 시 매개값으로 전달된다. main() 메소드 중괄호 { } 내에서 요구한 값을 얻을 수 있다.
5.12 열거(Enum) 타입
데이터 중 몇 가지로 한정된 값을 갖는 경우가 있다. 한정된 값을 갖는 타입을 열거 타입(enumeration type)이라고 한다. 열거 타입을 사용하기 위해서는 먼저 열거 타입 이름으로 소스 파일(.java)을 생성하고 한정된 값을 코드로 정의해야 한다. 열거 타입 이름은 첫 문자를 대문자로 하고 캐멀(camel) 스타일로 지어주는 것이 관례이다.
'JAVA 개념 > Part 02; 객체 지향 프로그래밍' 카테고리의 다른 글
[이것이 자바다] CHAPTER 11. 예외 처리 (1) | 2024.06.11 |
---|---|
[이것이 자바다] CHAPTER 09. 중첩 선언과 익명 객체 │ 개념 (0) | 2024.06.08 |
[이것이 자바다] CHAPTER 08. 인터페이스 │ 개념 (1) | 2024.06.08 |
[이것이 자바다] CHAPTER 07. 상속 │ 개념 (0) | 2024.06.08 |