본문 바로가기
Programming/Java

참조타입, 배열, 열거타입

참조타입: 기본타입(int, boolean 등) 제외한 나머지 형태.  객체 번지(주소) 참조 (클래스, 등)

기본타입은 실제 값을 변수 안에 저장하지만 참조타입은 메모리 번지(주소= 객체)에 저장.

변수안에 저장된 것이 아니고 객체를 참조하기때문에 참조타입인 것이다.

 

이걸 이해해야 객체지향프로그래밍, 상속 등을 이해할 수 있음!

 

참조변수(객체)가 없는 경우 null로 정의해야 함

String str = null;

NullPointException : null값인 객체에 무언갈 확인하려고하면 생기는 오류 (객체가 없다는 이야기)

 

 

 

 

참조변수의 예제는 다음과 같다.

String name1 = "신용권";
String name2 = "신용권";

이렇게 되면 1과 2는 둘 다 같은 '신용권' 값(객체, object)을 참조하므로 name1의 값(참조=객체)을 바꾸면

2도 같이 자동으로 바뀐다. 같은 주소값(객체)을 참조하고 있던 두 변수이기 때문이다.

 

이를 구분지어서 일괄 변경이 안되게하려면 new를 추가해야한다.

String name1 = "신용권";
String name2 = "신용권";
String name3 = new String("신용권");

여기서

name1 == name2   <- 이 경우 True가 나온다. (같은 주소를 참조. 객체가 같다.)

그러나 name1 == name3 <- False이다. (두 객체가 다르다)

 

 

객체와 상관없이 내부 문자열을 비교하기위해서는 equals() 메소드를 사용한다.

boolean result = str1.equals(str2); //str1과 str2의 문자열 값만 비교한다.

 

 

이미 존재하던 객체를 삭제하는 방법은 null을 이용한다.

String hobby = "여행";  //여행이라는 객체가 있던 참조변수 hobby는
hobby = null;   // null이 입력되면서 객체가 없어졌다.

이러한 String 객체는 JVM에서 쓰레기 객체로 취급하고 Gabage Collector를 이용해서 메모리에서 자동 제거한다.

사실 이런 건 보기 안좋으므로 타인의 코드가독성을 위해 지워놓는게 낫다.

 

 

null값이 지정되어 객체가 사라진 참조변수이더라도 다시 값을 지정하면 객체(참조)가 생긴다.

 

 

예제

package sec01.exam01;

public class StringEqualsExample {
	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는 문자열이  같음");
		}		
	} 
}

strVar1과 strVar2는 참조가 같음

strVar1과 strVar2는 문자열이 같음

strVar3과 strVar4는 참조가 다름

strVar3과 strVar4는 문자열이 같음

 

 

 

 

 

 


배열(array): 같은 타입의 데이터만 저장 가능한 인덱스(0부터 시작)가 부여된 자료. 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없음. 참조타입이다. python의 tuple보다 더 빡빡한 느낌

 

예제(for문을 이용한 여러 score 데이터를 한번에 처리)

int sum = 0;
for (int i=0; i<30; i++) {
     sum += scroe[i];
}
int avg = sum / 30;

 

 

배열 선언은 다음과 같다.

타입[] 변수 = { 값0, 값1, ... };   // 형식
int[] scores = {90, 85, 87, ...};  // 예제

scores[1]   = 100;   <- 85점이 100으로 바뀜

 

 

 

한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다. new를 이용해야 한다.

타입[] 변수; // 배열 선언
변수 = {값0, 값1, ... };    // 컴파일 에러. 이미 배열이 선언되었으므로 수정불가
변수 = new {값0, 값1, ...}; // 이렇게 해야 정의가 됨

int[] intArray = new int[5]; // 길이가 5인 배열을 생성한다.

 

 

종합 예제

package sec02.exam01;

public class ArrayCreateByValueListExample1 {
	public static void main(String[] args) {
		int[] scores = { 83, 90, 87 }; // 배열(array)을 만들때는 type 선언 후 []를 입력한다.
		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);
	}
}

scores[0] : 83

scores[1] : 90

scores[2] : 87

총합 : 260

평균 : 86.66666666666667

 

 

 

 

length는 배열의 길이를 출력한다. (0부터 세는거 아님!)

package sec02.exam04;

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);
		// length를 쓰면 배열의 길이를 출력한다.
		double avg = (double) sum / scores.length;
		System.out.println("평균 : " + avg);
	}
}

총합 : 260

평균 : 86.66666666666667

 

 

 

 

 

 

행과 열로 된 2차원 배열 만들기: [][] 2개 입력

int [][] scores = new int[2][3];

2 x 3 matrix를 생성한다.

 

package sec02.exam06;

public class ArrayInArrayExample {
	public static void main(String[] args) {	
		
		int[][] mathScores = new int[2][3];   // 2 x 3 mtx
		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][];    // 행렬이 아닌 계단구조형 2행 배열!
		englishScores[0] = new int[2];   // 첫째 행의 열 길이 2로 지정
		englishScores[1] = new int[3];   // 둘째 행의 열 길이 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} }; // 1행은 2열, 2행은 3열 구성
		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]);
			}
		}
	} 
}

mathScores[0][0]=0                     처음 숫자는 행, 둘째 숫자는 열이다. 숫자는 0으로 시작. 2 x 3 mtx에 대해서

mathScores[0][1]=0       1행 2열                  mathScores.length   <- 전체 행의 개수 = 2 

mathScores[0][2]=0       1행 3열                  mathScores.length[0]  <- 첫째 행의 열 길이  = 3

mathScores[1][0]=0       2행 1열                  mathScores.length[1]  <- 둘째 행의 열 길이  = 3

mathScores[1][1]=0       2행 2열 

mathScores[1][2]=0       2행 3열

 

englishScores[0][0]=0    1행 1열            배열을 선언하고 아무것도 넣지 않으면 0만 나온다.

englishScores[0][1]=0    1행 2열

englishScores[1][0]=0    2행 1열

englishScores[1][1]=0    2행 2열

englishScores[1][2]=0    2행 3열

 

javaScores[0][0]=95

javaScores[0][1]=80

javaScores[1][0]=92

javaScores[1][1]=96

javaScores[1][2]=80

임의로 변수와 크기를 선언할 때는 편안하게 일반 숫자 크기로 선언하지만

index 값을 찾을 때에는 0부터 센다는 것에 유의하자.

 

 

참조 변수가 들어간 경우도 개념만 그대로 적용한다.

package sec02.exam07;

public class ArrayReferenceObjectExample {
	public static void main(String[] args) {		
		String[] strArray = new String[3];  // 3행 생성
		strArray[0] = "Java";
		strArray[1] = "Java";
		strArray[2] = new String("Java");

		System.out.println( strArray[0] == strArray[1]);
		System.out.println( strArray[0] == strArray[2] );    
		System.out.println( strArray[0].equals(strArray[2]) );
	} 
}

true    -> 둘의 참조 주소(객체)가 같다.

false  ->  new로 선언된 것은 문자열은 같아도 객체가 다르다.

true    ->  new로 선언되었던 객체이지만 문자열 값 자체는 같다.

 

 

 

 

배열 복사: System.arraycopy(원본배열, 원본 시작인덱스, 새 배열, 새 배열 붙여넣을 시작 인덱스, 복사개수)

(객체는 같은 것을 참조)

package sec02.exam09;

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문: 특정 동작을 위한 것이다. 배열 항목 개수 만큼 반복 후 자동 종료.

package sec02.exam10;

public class AdvancedForExample {
	public static void main(String[] args) {
		int[] scores = { 95, 71, 84, 93, 87 };
		
		int sum = 0;
		for (int score : scores) {  // for (타입 저장할 장소 : 정보를 가져올 배열)
			sum = sum + score;
		}
		System.out.println("점수 총합 = " + sum);
		
		double avg = (double) sum / scores.length;
		System.out.println("점수 평균 = " + avg);

	} 
}

점수 총합 = 430

점수 평균 = 86.0

 

 

 

 

 

 

 

 

 


열거타입 (public enum): 한정된 값을 갖는 것. (ex> week;월화수목금 등)

열거타입도 참조타입처럼 개별 객체가 존재한다. (기본 타입 제외 나머지 다 참조타입이다)

package sec03.exam01;

public enum Week {
	  MONDAY,
	  TUESDAY,
	  WEDNESDAY,
	  THURSDAY,
	  FRIDAY,
	  SATURDAY,
	  SUNDAY
}

enum 이름 { 열거 상수 } 구조로 선언된다. public enum은 반드시 소문자로 작성한다.

 

이렇게 만들어진 java파일은 하나의 타입으로 선언이 가능하다.

 

import sec03.exam01.Week; // java 파일이 있는 상태에서

Week today = Week.SUNDAY;  // Week type으로 today란 이름에 SUNDAY 객체 참조.

today와 SUNDAY는 같은 객체를 사용한다.

 

 

package sec03.exam02;

import java.util.Calendar; // Calendar class는 컴퓨터 날짜 요일 시간을 가져온다.

import sec03.exam01.Week;  // Week 타입을 이용하기위함이다.

public class EnumWeekExample {
	public static void main(String[] args) {
		Week today = null;   // 열거타입 변수선언
		
		Calendar cal = Calendar.getInstance(); // cal이름으로 Calaender 객체화
		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("열심히 자바 공부합니다.");
		}
	}
}

오늘 요일: FRIDAY

열심히 자바 공부합니다.

 

이 글을 작성 마무리한 날은 금요일이므로 출력 결과는 적절하다.

 

 

728x90
반응형

'Programming > Java' 카테고리의 다른 글