-
이것이 자바다 | 5강_참조타입JAVA/이것이 자바다 2022. 1. 25. 01:15
1. 자바의 데이터 타입
기본타입
- 정수타입
- 실수타입
- 논리타입(boolean)
참조타입
- 배열타입
- 열거타입
- 클래스
- 인터페이스
기본타입과 참조타입의 차이점
- 기본타입: 실제 값을 변수에 저장
- 참조타입: 메모리의 번지를 값으로 가짐
2. 메모리 사용 영역
메소드 영역
- JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역
힙 영역
- 객체와 배열이 생성되는 영역
- 해당 영역에 생성되는 객체와 배열이 참조하는 변수나 필드가 없다면 의미 없는 객체가 되므로 이것을 쓰레기 취급하고 JVM이 쓰레기 수집기를 실행시켜 쓰레기 객체를 자동 제거한다.
JVM 스택 영역
- 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당됨
- 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거한다.
3. NullPointerException
참조 타입 변수가 null을 가지고 있을 경우, 사용할 수 없다. (NullPointerException)
-> 참조 타입 변수를 사용하는 것은 곧 객체를 사용하는 것을 의미하는데, 참조할 객체가 없으므로 사용할 수 없음.
int[] intArray = null; intArray[0] = 10; //NullPointerException
String str = null; System.out.println("총 문자수: " + str.length()); //NullPointerException
4. String 타입
1>
String name1 = "신용권"; String name2 = "신용권";
위의 경우 name1과 name2는 동일한 String 객체를 참조함
2>
String name1 = new String("신용권"); String name2 = new String("신용권");
위의 경우 new연산자(객체 생성 연산자)에 의해 힙 영역에 새로운 객체를 만들어 서로 다른 String 객체를 참조함.
-> 1의 경우 name1 == name2가 true이지만, 2의 경우 false가 나옴.
=> 문자열만을 비교할 때에는 String 객체의 equals() 메소드를 사용해야 함.
//예시 boolean result = str1.equals(str2);
문자열 비교
package chap05; public class StringEqualExample { public static void main(String[] args) { String strVar1 = "신민철"; String strVar2 = "신민철"; if(strVar1 == strVar2) { System.out.println("strVar1과 strVar2는 참조가 같음"); } else { System.out.println("strVar1과 strVar2는 참조가 다름"); } if(strVar1.equals(strVar2)) { System.out.println("strVar1과 strVar2는 문자열이 같음"); } String strVar3 = new String("신민철"); String strVar4 = new String("신민철"); if(strVar3 == strVar4) { System.out.println("strVar3과 strVar4는 참조가 같음"); } else { System.out.println("strVar3과 strVar4는 참조가 다름"); } if(strVar3.equals(strVar4)) { System.out.println("strVar3과 strVar4는 문자열이 같음"); } } }
null은 String변수가 참조하는 String 객체가 없다는 뜻임.
String hobby = null;
5. 배열 타입
만약 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생한다.
-> 배열 변수는 배열을 생성하고 참조하는 상태에서 값을 저장하거나 읽어야 한다.
String[] names = { "신용권", "홍길동", "감자바"}; names[1] = "홍삼원"; //대입 연산자를 사용하여 바꿀 수 있음
package chap05; public class ArrayCreateByValueListExample1 { public static void main(String[] args) { int[] scores = { 83, 90, 87 }; System.out.println("scores[0] : " + scores[0]); System.out.println("scores[1] : " + scores[1]); System.out.println("scores[2] : " + scores[2]); int sum = 0; for (int i = 0; i < 3; i++) { sum += scores[i]; } System.out.println("총합 : " + sum); double avg = (double) sum / 3; System.out.println("평균 : " + avg); } }
배열 변수를 이미 선언한 후에 다른 실행문에서 중괄호를 사용한 배열 생성은 허용되지 않음.
타입[] 변수; 변수 = { 값0, 값1, 값2, 값3, ... }; //컴파일 에러
-> new 연산자를 사용해서 값 목록을 지정해주면 됨
ex)
String[] names = null; names = new String[] {"신용권", "홍길동", "김자바"};
매소드의 매개값이 배열일 경우: 값 목록으로 배열을 생성함과 동시에 메소드의 매개값으로 사용하고자 할 때는 반드시 new연산자를 사용해야 한다.
int add(int[] scores { ... } _______________________________________________ int result = add ( {95, 85, 90} ); // 컴파일 에러 int result = add( {new int[] {95, 85, 90} );
*값의 목록을 가지고 있지 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면 new연산자로 배열 객체를 생성시킬 수 있다.
타입[] 변수 = new 타입[길이];
new 연산자로 배열 생성
package chap05; public class ArrayCreateByNewExample { public static void main(String[] args) { int[] arr1 = new int[3]; for(int i = 0; i < 3; i++) { System.out.println("arr1[" + i + "] : " + arr1[i]); //0으로 초기값이 설정되기 때문에 0 출력 } arr1[0] = 10; arr1[1] = 20; arr1[2] = 30; for(int i = 0; i < 3; i++) { System.out.println("arr1[" + i + "] : " + arr1[i]); } double[] arr2 = new double[3]; for(int i = 0; i < 3; i++) { System.out.println("arr2[" + i + "] : " + arr2[i]); } arr2[0] = 0.1; arr2[1] = 0.2; arr2[2] = 0.3; for(int i = 0; i < 3; i++) { System.out.println("arr2[" + i + "] : " + arr2[i]); } String[] arr3 = new String[3]; for(int i = 0; i<3; i++) { System.out.println("arr3[" + i + "] : " + arr3[i]); } arr3[0] = "1월"; arr3[1] = "2월"; arr3[2] = "3월"; for(int i = 0; i < 3; i++) { System.out.println("arr3[" + i + "] : " + arr3[i]); } } }
6. 배열 길이
배열의 length 필드
package chap05; public class ArrayLengthExample { public static void main(String[] args) { int[] scores = { 83, 90, 87 }; int sum = 0; for ( int i = 0; i < scores.length; i++) { sum += scores[i]; } System.out.println("총합 : " + sum); double avg = (double) sum / scores.length; System.out.println("평균 : " + avg); } }
7. 커맨드 라인 입력
public static void main(String[] args) { ... }
String[] args 사용 이유:
"java 클래스"로 프로그램을 실행하면 JVM은 길이가 0인 String 배열을 먼저 생성하고 main() 메소드를 호출할 때 매개값으로 전달한다.
String[] args = { };
// main() 메소드 호출 시 전달
public static void main(String[] args) {
...
}
다음과 같이 "java 클래스" 뒤에 공백으로 구분된 문자열 목록을 주고 실행하면, 문자열 목록으로 구성된 String[] 배열이 생성되고 main() 메소드를 호출할 때 매개값으로 전달된다.
java 클래스 문자열0 문자열1 문자열2 문자열3 문자열4 ... 문자열n-1
String[] args = {문자열0, 문자열1, 문자열2, 문자열3, 문자열4, ... , 문자열n-1};
public static void main(String[] args) {
...
}
main() 메소드의 매개 변수
package chap05; public class MainStringArrayArgument { public static void main(String[] args) { if(args.length != 2) { // 입력된 데이터 개수가 두 개가 아닐 경우 System.out.println("프로그램의 사용법"); System.out.println("java MainStringArrayArgument num1 num2"); System.exit(0); //프로그램 강제 종료 } String strNum1 = args[0]; //첫 번째 데이터 얻기 String strNum2 = args[1]; //두 번째 데이터 얻기 int num1 = Integer.parseInt(strNum1); //문자열을 정수로 변환 int num2 = Integer.parseInt(strNum2); //문자열을 정수로 변환 int result = num1 + num2; System.out.println(num1 + " + " + num2 + " = " + result); } }
8. 다차원 배열
int[][] scores = new int[2][3];
-> 2 x 3 행렬의 구조
(0,0) (0,1) (0,2) (1,0) (1,1) (1,2) 계단식 구조도 가능
int[][] scores = new int[2][]; scores[0] = new int[2]; scores[1] = new int[3];
scores.length //2 scores[0].length //2 scores[1].length //3
배열 속의 배열
package chap05; public class ArrayInArrayExample { public static void main(String[] args) { int[][] mathScores = new int[2][3]; for(int i = 0; i < mathScores.length; i++) { for(int k = 0; k < mathScores[i].length; k++) { System.out.println("mathScores["+i+"]["+k+"]=" +mathScores[i][k]); } } System.out.println(); int[][] englishScores = new int[2][]; englishScores[0] = new int[2]; englishScores[1] = new int[3]; for(int i = 0; i < englishScores.length; i++) { for(int k = 0; k < englishScores[i].length; k++) { System.out.println("englishScores["+i+"]["+k+"]="+englishScores[i][k]); } } System.out.println(); 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+"]="+javaScores[i][k]); } } } }
9. 객체를 참조하는 배열
String[] 배열의 항목도 String변수와 동일하게 취급되어야 한다.
-> String[] 배열 항목 간에 문자열을 비교하기 위해서는 ==연산자 대신 equals() 메소드를 사용해야 한다.
String[] strArray = new String[3]; strArray[0] = "Java"; strArray[1] = "Java"; strArray[2] = new String("Java"); System.out.println(strArray[0] == strArray[1]); //true (같은 객체를 참조) System.out.println(strArray[0] == strArray[2]); //false (다른 객체를 참조) System.out.println(sreArray[0].equals(strArray[2])); //true (문자열이 동일
10. 배열 복사
배열을 한 번 생성하면 크기를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 항목 값들을 복사해야 한다.
배열 간의 항목 값들을 복사하는 방법
- for문 사용
- System.arraycopy() 메소드 사용
for 문으로 배열 복사
package chap05; public class ArrayCopyByForExample { public static void main(String[] args) { 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.arraycopy() 로 배열 복사
package chap05; public class ArrayCopyExample { public static void main(String[] args) { String[] oldStrArray = { "java", "array", "copy" }; String[] newStrArray = new String[5]; System.arraycopy(oldStrArray, 0, newStrArray, 0, oldStrArray.length); for(int i = 0; i < newStrArray.length; i++) { System.out.print(newStrArray[i] + ", "); } } }
-> java, array, copy, null, null,
얕은 복사 : 참조 타입 배열일 경우, 배열 복사가 되면 복사되는 값이 객체의 번지이므로 새 배열의 항목은 이전 배열의 항목이 참조하는 객체와 동일하다.
향상된 for문
반복 실행을 하기 위해 카운터 변수와 증감식을 사용하지 않음
배열 및 컬렉션 항목의 개수만큼 반복하고, 자동적으로 for문을 빠져나간다.
- for ( 배열에서 꺼낸 항목을 저장할 변수 : 배열 ) { ... }
package chap05; public class AdvancedForExample { public static void main(String[] args) { int[] scores = { 95, 71, 84, 93, 87 }; int sum = 0; for ( int score : scores ) { //배열에서 꺼낸 항목을 저장할 변수 선언 : 배열 sum = sum + score; } System.out.println("점수 총합 = " + sum); double avg = (double) sum / scores.length; System.out.println("점수 평균 = " + avg); } }
11. 열거 타입
- 열거 타입 이름으로 소스파일(.java)생성
- 열거 타입의 이름은 관례적으로 첫 문자가 대문자
- 열거 상수(열거 타입의 값)은 관례적으로 모두 대문자
ex) public enum LoginResult { LOGIN_SUCCESS, LOGIN_FAILED }
※ 자바는 Date, Calendar, LocalDateTime 등의 클래스를 제공한다.
Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR); //년 int month = now.get(Calendar.MONTH); //월 int day = now.get(Calendar.DAY_OF_MONTH); //일 int week = now.get(Calendar.DAY_OF_WEEK); //요일 int hour = now.get(Calendar.HOUR); //시간 int minute = now.get(Calendar.MINUTE); //분 int second = now.get(Calendar.SECOND); //초
열거 타입과 열거 상수
package chap05; import java.util.Calendar; public class EnumWeekExample { public static void main(String[] args) { Week today = null; //열거타입 변수 선언 Calendar cal = Calendar.getInstance(); int week = cal.get(Calendar.DAY_OF_WEEK); //일(1) ~ 토(7) switch(week) { case 1: today = Week.SUNDAY; break; case 2: today = Week.MONDAY; break; case 3: today = Week.TUESDAY; break; case 4: today = Week.WEDNESDAY; break; case 5: today = Week.THURSDAY; break; case 6: today = Week.FRIDAY; break; case 7: today = Week.SATURDAY; break; } System.out.println("오늘 요일: "+ today); if(today == Week.SUNDAY) { System.out.println("일요일에는 축구를 합니다."); } else { System.out.println("열심히 자바 공부를 합시다."); } } }
'JAVA > 이것이 자바다' 카테고리의 다른 글
이것이 자바다 | 5장 확인문제 9번 (0) 2022.06.27 이것이 자바다 | 5강_열거 객체의 메소드 (0) 2022.06.27 이것이 자바다 | 4강_연습문제 (0) 2022.01.24 이것이 자바다 | 4강_조건문과 반복문 (0) 2022.01.17 이것이 자바다 | 3강_연산자 (0) 2022.01.13