Difference between revisions of "컴퓨터프로그래밍및실습 (2022년)/0919"
Jump to navigation
Jump to search
m (Swpark moved page 컴퓨터프로그래밍및실습 (2022년)/참조 타입 to 컴퓨터프로그래밍및실습 (2022년)/0922 over a redirect without leaving a redirect) |
m (Swpark moved page 컴퓨터프로그래밍및실습 (2022년)/0922 to 컴퓨터프로그래밍및실습 (2022년)/0919 without leaving a redirect) |
Revision as of 21:13, 21 July 2022
데이터 타입 분류
- 기본 타입(primitive type)
- 정수 타입
- byte
- char
- short
- int
- int
- long
- 실수 타입
- float
- double
- 논리 타입
- boolean
- 정수 타입
- 참조 타입(reference type)
- 배열 타입(array type)
- 열거 타입(enumeration type)
- 클래스(class)
- 인터페이스(interface)
// 기본 타입 변수
int age = 25;
double price = 100.5
// 참조 타입 변수(reference type variable)
String name = "신용권"; // 객체는 힙(heap) 영역에 존재한다.
String hobby = "독서";
- 참조 변수인 name에는 "신용권" 객체가 저장되어 있는 메모리의 주소가 저장되어 있다.
- 교재 p.139 그림 참조
메모리 사용 영역
- 교재 p.140 그림 참조
- 메소드(method) 영역
- Java 소스 코드(XXX.java)를 컴파일하여 만들어진 실행 코드(bytecode) (XXX.class)가 적재된 메모리 영역
- 클래스 로더(class loader)가 class 파일을 읽어 메모리에 올림
- 상수풀(runtime constant pool), 필대(field) 데이터, 메소드(method) 데이터, 메소드 코드, 생성자(construct) 코드 등 실행에 필요한 바이트코드 및 상수, 전역 변수(클래스 변수, class field)
- 힙(heap) 영역
- 프로그래머가 생명 주기(life time)을 제어할 수 있는 메모리가 위치하는 영역임
- new 연산자를 이용하여 생성하는 객체
- 배열, String도 객체이므로 힙에 존재함
- new 연사자를 호출하여 객체를 생성하면 만들어지고, garbage가 되면 사라짐
- 스택(stack) 영역
- 스택 영역은 스레드 마다 독립적으로 존재함
- 특별히 스레드를 만들지 않았다면 main 메소드가 실행되고 있는 main 스레드만 존재하므로 스택 영역도 하나임
- 메소드의 인자, 지역 변수(local variable), 리턴 값, 리턴 주소가 저장됨. 이를 activation record라 부름.
- p.142 그림 참조
- 아래 코드에서 (1), (2), (3) 지점에서의 스택 영역의 형태는?
char v1 = 'A'; // (1)
if (v1 == 'A') { // (2)
int v2 = 100;
double v3 = 3.14;
}
boolean v4 = true; // (3)
참조 변수의 ==, != 연산
- 교재 p.143 그림 참조
refVar1 = 객체_1;
refVar2 = 객체_2;
refVar3 = 객체_2;
refVar1 == refVar2 // 결과 : false
refVar1 != refVar2 // 결과 : true
refVar2 == refVar3 // 결과 : true
refVar2 != refVar3 // 결과 : false
null과 NullPointerException
refVar1 = 객체_1;
refVar2 = null;
refVar1 == null // 결과 : false
refVar1 != null // 결과 : true
refVar2 == null // 결과 : true
refVar2 != null // 결과 : false
int[] intArray = null;
intArray[0] = 10; // NullPointerException 발생
String str = null;
System.out.println("총 문자수 : " + str.length()); // NullPointerException 발생
String 타입
- String은 상수 객체이다. 왜냐하면 String에는 자신이 가진 값을 변경하는 메소드가 없기 때문이다.
String 변수 = "문자열";
String name;
name = "신용권";
String hobby = "자바";
hobby = null; // garbage가 된다.
String name1 = "신용권";
String name2 = "신용권"; // 리터럴이 동일하면 동일한 객체를 가리킴
name1 = "신민철";
name2 = "신민철";
String name3 = new String("신민철");
boolean result = name1 == name2; // true
result = name1 == name3; // false
result = name1.equals(name3); // true;
배열 타입
- 동일한 타입을 여러 개 만들어야 할 때
배열이라?
- 다음은 성가시다.
int score1 = 83;
int score2 = 90;
int score3 = 87;
int score4 = 99;
int score5 = 48;
int score6 = 21;
int score7 = 38;
int score8 = 83;
int score9 = 78;
int score10 = 92;
int score11 = 95;
int score12 = 29;
int score13 = 55;
int score14 = 66;
int score15 = 88;
int score16 = 77;
int score17 = 44;
int score18 = 34;
int score19 = 84;
int score20 = 81;
int score21 = 60;
int score22 = 85;
int score23 = 44;
int score24 = 23;
int score25 = 84;
int score26 = 48;
int score27 = 40;
int score28 = 58;
int score29 = 78;
int score30 = 75;
- 평균을 구하고자 한다면 코드를 어떻게 작성해야 하나?
int sum = score1;
sum += score2;
sum += score3;
sum += score4;
sum += score5;
sum += score6;
sum += score7;
sum += score8;
sum += score9;
sum += score10;
sum += score11;
sum += score12;
sum += score13;
sum += score14;
sum += score15;
sum += score16;
sum += score17;
sum += score18;
sum += score19;
sum += score20;
sum += score21;
sum += score22;
sum += score23;
sum += score24;
sum += score25;
sum += score26;
sum += score27;
sum += score28;
sum += score29;
sum += score30;
int avg = sum / 30;
- 얼마나 번거러운가? 아래와 같이 바꿔보자.
// score는 배열이다.
int[] score = {83, 90, 87, 99, 48, 21, 38, 83, 78, 92, 95, 29, 55, 66, 88, 77, 44, 34, 84, 81, 60, 85, 44, 23, 84, 48, 40, 58, 78, 75};
int sum = 0;
for(int i = 0; i < score.length; i++) // 여기서 score.length는 30
sum += score[i]; // score[0]는 83, score[1]은 90 ...
int avg = sum / score.length;
- 왜 배열이 필요한지 이해가 되는가?
배열 선언
- 두 표현은 동일하다.
int[] intArray; | int intArray[]; |
double[] doubleArray; | double doubleArray[]; |
String[] strArray; | String strArray[] |
- 참고할 배열이 없다면
null
로 지정한다.
int[] intArray = null;
값 목록으로 배열 선언
String[] names = { "신용권", "홍길동", "감자바" };
names[1] = "홍삼원";
//--------------------------------------
String[] names = null;
names = new String[] { "신용권", "홍길동", "감자바" };
//--------------------------------------
// 다음과 같은 add 메소드가 있다면
int add(int[] scores) {
int sum = 0;
for(int i = 0; i < scores.length; i++)
sum += scores[i];
return sum;
}
// 이를 호출하는 방법으로
int result = add( {95, 85, 90} ); // 컴파일 에러 발생
int result = add( new int[] {95, 85, 90} ); // OK
new 연산자로 배열 생성
int[] scores = new int[30]; // 앞의 예제에서 빈 배열을 만들고자 한다면. 모두 0으로 초기화된다.
scores[0] = 83; // 인덱스는 0부터 시작한다.
scores[1] = 90;
scores[2] = 75;
String[] names = new String[30]; // 모두 null로 초기화된다.
names[0] = "신용권";
names[1] = "홍길동";
names[2] = "감자바";
배열 길이
int[] intArray = { 10, 20, 30 };
System.out.println(intArray.length); // 3이 출력됨
intArray.length = 10; // 에러. length는 상수이다. 즉, 값을 변경할 수 없다.
커맨드 라인(command line) 입력
- 명령창에서 다음과 같이 Java 프로그램 실행
C:> java MainStringArrayArgument 10 20
- 코드
public class MainStringArrayArgument {
public static void main(String[] args) {
if (args.length != 2) { // 입력 데이터가 2개가 아닌 경우
System.out.println("Usage: java MainStringArrayArgument num1 num2");
System.exit(0); // 프로그램 강제 종료
}
String strNum1 = args[0];
String strNum2 = args[1];
int num1 = Integer.parseInt(strNum1); // Integer 클래스의 parseInt 메소드를 이용하여 문자열을 정수로 변환
int num2 = Integer.parseInt(strNum2);
int result = num1 + num2;
System.out.println(num1 + "+" + num2 + "=" + result);
}
}
- 실행 결과
10+20=30
다차원 배열
int[][] scores = new int[2][3];
System.out.println(scores.length); // 2
System.out.println(scores[0].length); // 3
System.out.println(scores[1].length); // 3
//--------------------------------------------
int[][] scores = new int[2][];
scores[0] = new int[2];
scores[1] = new int[3];
System.out.println(scores.length); // 2
System.out.println(scores[0].length); // 2
System.out.println(scores[1].length); // 3
//--------------------------------------------
// 다차원 배열 초기화
int[][] scores = { {95, 80}, {92, 96} };
System.out.println( scores[0][0] ); // 95
System.out.println( scores[1][1] ); // 96
int[][] javaScores = { {95, 80}, {92, 96, 80} };
for(int i = 0; i < javaScores.length; i++) {
for(int k = 0; k < javaScores[i].length; k++) {
System.out.println( javaScores[i][k] );
}
}
배열 복사
- 예제 코드
public class ArrayCopyExample {
public static void main(String[] args) {
// for 문 이용
int[] oldIntArray = { 1, 2, 3 };
int[] newIntArray = new int[5];
for(int i = 0; i < oldIntArray.length; i++)
newIntArray[i] = oldIntArray[i];
for(int i = 0; i < newIntArray.length; i++)
System.out.print(newIntArray[i] + "," );
System.out.println();
// arraycopy 이용
String[] oldStrArray = { "java", "array", "copy" };
String[] newStrArray = new String[5];
System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length); // p.169 그림 참조
for(int i = 0; i < newStrArray.length; i++)
System.out.print(newStrArray[i] + ", ");
System.out.println();
}
}
- 실행 결과
1,2,3,0,0,
java, array, copy, null, null,
향상된 for 문
package ch05;
public class ArrayCopyExample {
public static void main(String[] args) {
// for 문 이용
int[] oldIntArray = { 1, 2, 3 };
int[] newIntArray = new int[5];
for(int i = 0; i < oldIntArray.length; i++)
newIntArray[i] = oldIntArray[i];
for(int value : newIntArray) // ← 배열 전체를 스캔하는데 인덱스가 필요없음
System.out.print(value + "," );
System.out.println();
// arraycopy 이용
String[] oldStrArray = { "java", "array", "copy" };
String[] newStrArray = new String[5];
System.arraycopy(oldStrArray, 0, newStrArray, 0, oldIntArray.length);
for(String str : newStrArray) // ← 배열 전체를 스캔하는데 인덱스가 필요없음
System.out.print(str + ", ");
System.out.println();
}
}
열거 타입(Enumeration Type)
- Java에서 이름 짓는 법
종류 | 예 | 설명 |
---|---|---|
변수 | name | 소문자를 이용하여 짓는다. 영어가 아닌 한국어로 변수 이름을 지어도 되지만 관례적으로 로마자를 사용한다. |
myName, myFirstName | 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다. | |
메소드 | move() | 소문자로 짓는다. 이름 뒤에 연이어 괄호가 나오기 때문에 이름으로 변수와 메소드를 구분할 수 있다. |
moveLeft() | 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다. | |
클래스, 인터페이스, 열거형 | Car | 시작 문자를 대문자로 한다. |
BlueCar | 두 개의 단어가 연이어 나오면 새로운 단어의 시작은 대문자로 한다. | |
상수(static final) | COLOR | 모든 문자를 대문자로 한다. |
BLUE_COLOR | 두 개의 단어가 연이어 나오면 단어 사이에 _를 붙인다. |
열거 타입 선언
- 상수를 여러 개 만들고 싶을 때
public enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY };
public enum LoginResult { LOGIN_SUCCESS, LOGIN_FAILED };
Week today;
Week reservationDay;
Week birthday = null;
today = Week.SUNDAY;
if (today == Week.SUNDAY) { // true
- Calendar 객체를 이용한 열거형 연습
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR); // 년
int month = now.get(Calendar.MONTH) + 1; // 월
int day = now.get(Calendar.DAY_OF_MONTH); // 일
int week = now.get(Calendar.DAY_OF_WEEK); // 요일 (1~7)
int hour = now.get(Calendar.HOUR); // 시간
int minute = now.get(Calendar.MINUTE); // 분
int second = now.get(Calendar.SECOND); // 초
열거 객체의 메소드
- 열거 객체는 java.lang.Enum 클래스로부터 상속받음.
리턴 타입 | 메소드(매개 변수) | 설명 |
---|---|---|
String | name() | 열거 객체의 문자열을 리턴 |
int | ordinal() | 열거 객체의 순번(0부터 시작)을 리턴 |
int | compareTo() | 열거 객체를 비교하여 순번 차이를 리턴 |
열거 타입 | valueOf(String name) | 주어진 문자열의 열거 객체를 리턴 |
열거 배열 | values() | 모든 열거 객체들을 배열로 리턴 |
Week today = Week.SUNDAY;
String name = today.name(); // "SUNDAY"
int ordinal = today.ordinal(); // 6. 0부터 시작하여 6번째 데이터라는 뜻임
Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;
int result1 = day1.compareTo(day2); // -2 (0 - 2)
int result2 = day2.compareTo(day1); // 2 (2 - 0)
Week weekDay = Week.valueOf("SATURDAY"); // Week.SATURDAY
Week[] days = Week.values();
for(Week day : days)
System.out.println(day);