본문 바로가기

dev/Java

[Java]참조타입변수 - 클래스/배열/열거타입

메모리 사용 영역

  : java.exe로 JVM이 시작되면 운영체제에서 받은 메모리영역(Runtime Data Area) 세부영역으로 구분해 사용한다.

- 메소드(Method) 영역

  : JVM 시작할 때 생성되고, 모든 스레드가 공유하는 영역.

   클래스 로더로 읽어 클래스별 런타임상수풀/필드데이터/메소드데이터/메소드코드/생성자코드 등으로 분류해 저장

- 힙(Heap) 영역

  : 객체, 배열이 생성되는 영역으로 스택 영역의 변수나 다른 객체의 필드에서 참조한다.

    참조하는 변수, 필드가 없으면 의미가 없는 객체가 되기 때문에 GarbageCollector를 실행시켜 힙 영역에서 자동 제거

- 스택(Stack) 영역

  : 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.

   메서드 호출할 때마다 프레임 추가(push), 메서드 종료되면 프레임 제거(pop)

   프레임 내부에는 로컬 변수 스택이 있는데 기본/참조 타입 변수가 추가/제거된다. 

 

참조타입변수

==, !=연산

  : 동일 객체를 참조하는지, 다른 객체를 참조하는지 알아볼 때 사용. (주소 값 비교)

   참조타입변수가 null값을 가지고 있는 경우 참조할 객체가 없으므로 사용할 수 없음. 사용시 NullPointerException

 

- 클래스타입 _ String타입

  : 변수는 스택영역에 생성되고 문자열은 힙 영역에 String객체로 생성된다

문자열 리터럴로 생성 new연산자로 생성
    String name1 = "밍";
    String name2 = "밍";
    //name1, name2는 동일한 String객체를 참조한다.

    String name1 = new String("밍");
    String name2 = new String("밍");

    //new연산자를 이용해 직접 String객체를 생성시킨다.
    //name1, name2는 서로 다른 String객체를 참조한다.
==연산의 결과 true (변수에 저장된 객체의 주소가 같음) ==연산의 결과 false (변수에 저장된 객체의 주소가 다름)
문자열만 비교할 때는 String 객체의 equals()메서드를 사용한다.
equals(비교문자열): 원본 문자열과 매개값으로 주어진 비교문자열이 동일한지 비교 후 true/false를 리턴
id.equals(mid) && password.equals(mpassword)

- 배열타입

  : 힙영역에 배열 생성. 배열변수는 힙 영역의 배열객체를 참조

 

  배열: 같은 타입 데이터를 연속된 공간에 나열, 인덱스 부여해 놓은 자료구조

   ① 같은 타입의 데이터만 저장할 수 있다. int배열 = int값만 저장 가능, String배열 = 문자열만 저장 가능

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

      새로운 배열을 생성하고 기존 배열 항목을 새 배열로 복사해야한다.

배열 변수 선언 후 다른 실행문에서 중괄호를 사용한 배열생성 허용X. new 연산자를 이용해 값의 목록을 지정.
타입[] 변수;
변수 = { 값0, 값1, 값2, 값3, ...}; // error

int add(int[] scores) { ... }
int result = add( {95, 85, 90}); //error 
타입[] 변수;
변수 = new 타입[] { 값0, 값1, 값2, 값3, ...};

int add(int[] scores) { ... }
int result = add( new int[] {95, 85, 90});
값의 목록을 가지고 있지 않지만 향후 값들을 저장할 배열을 미리 만들고 싶은 경우. 배열변수 선언 후에도 가능
타입[] 변수 = new 타입[길이];
  int[] intArray = new int[5]; //intArray[0]~[4]
타입[] 변수 = null;
변수 = new 타입[길이];
변수[인덱스] = 값; //배열에 새로운 값 저장
  intAtrray[0] = 80;
배열 길이 구하기: 배열변수.length;
//length는 읽기 전용 필드이기 때문에 값을 바꿀 수 없음
//인덱스 범위를 초과하는 경우 ArrayIndexOutOfBoundsException 발생
public class ArrayEx1 {
	public static void main(String[] args) {
    
		char[] c_array = new char[4]; //변수 c_array에 주소할당. 해당 주소에 4개 저장
		c_array[0] = 'j';
		c_array[1] = 'a';
		c_array[2] = 'v';
		c_array[3] = 'a'; //마지막인덱스는 크기-1
        
	//	c_array[4] = 'a'; //배열은 한 번 만들어지면 늘어나거나 줄어들지않고 고정.
						  //4로 만들어놨기때문에 에러발생.
                          
		System.out.println(c_array[3]);
		
		for(int i = 0; i<4; i++) {
			System.out.print(c_array[i]);
		}
		
		System.out.println();
		
		//배열의 갯수 모를경우 자동으로 데이터의 갯수를 가져오는 length 사용
		for(int i = 0; i<c_array.length; i++) {
			System.out.print(c_array[i]);
		}
		
		int[] arr1 = {1,2,3,4,5}; //선언과 생성을 한 문장에서 해야함
		
	/*	int[] a;
		a = {1,2,3,4,5};    //선언과 생성을 동시에하지않으면 error
	*/
		int[] arr2 = new int[] {1,2,3,4,5}; //갯수 지정 X
		
	}

}
더보기
더보기

실행결과

a
java
java

public class ArrayEx2 {
	public static void main(String[] args) {
		//학생의 성적을 전달받아 배열에 저장, 제일 높은 성적을 출력하세요
		//80, 90, 70, 60, 75
		//최소값, 총점, 평균
		int[] report = {80, 90, 70, 60, 75};
		int max = report[0]; //80
		int min = report[0];
		int sum = report[0];
		for(int i=0; i <report.length; i++) {
			if(max<report[i]) {
				max = report[i];
			}
			if(min>report[i]) {
				min = report[i];
			}
			sum += report[i];		
		}
		System.out.println("최고성적:"+max);
		System.out.println("최저성적:"+min);
		System.out.println("총점:"+sum);
		
		double avg = sum/(double)report.length;
		System.out.println("평균:"+avg);	
	}
}
더보기
더보기

실행결과

최고성적:90
최저성적:60
총점:455
평균:91.0

  배열 복사

  System.arraycopy(원본배열, 복사할 항목의 시작인덱스, 새 배열, 새 배열에 붙여넣을 시작 인덱스, 복사할 개수);

  Arrays.copyOf(복사할배열, 길이): 0번부터 배열의 길이만큼 복사해 새로운 배열을 만든다.
  Arrays.copyOfRange(복사할배열, n, m-1): 배열의 일부분(n부터 m-1까지)을 복사해 새로운 배열을 만든다.

  - 얕은 복사(shallow copy)

     : 배열요소의 주소만 복사되므로 배열요소가 변경되면 복사된 배열의 값도 변경됨. 참조객체가 동일.

  - 깊은 복사(deep copy)

     : 서로 다른 인스턴스의 메모리 요소를 가지기 때문에 배열요소가 변경되어도 복사된 배열의 값에 영향이 없다.

      참조하는 객체 별도로 생성

public class ArrayCopyEx1 {
	public static void main(String[] args) {
		
		int[] arr1 = {1,2,3,4,5};
		int[] arr2 = new int[10]; //입력받을 공간 선언(int형 = 0이 저장되어있음)
		
		System.arraycopy(arr1,0,arr2,3,5);
	    //  System.arraycopy(arr1,2,arr2,3,5); //3 4 5 _ _
		
		for(int i : arr2) {
			System.out.print(i+"\t");
		}
	}
}

  향상된 for문

    : 증감식을 사용하지 않고 배열 및 컬렉션 항목의 개수만큼 반복, 자동으로 빠져나간다.

for(타입변수 : 배열){ 실행문; }
//java.util.Arrays: 배열을 다루는데 필요한 기능을 가지고있는 클래스
public class ArrayCopyEx2 {

	public static void main(String[] args) {
		
		int[] arr = {0,1,2,3,4};
		int[] arr2 = Arrays.copyOf(arr, arr.length);
		
		for(int i : arr2) {
			System.out.print(i+",");
		}
		System.out.println();
		
		int[] arr3 = Arrays.copyOf(arr, 3);
		for(int i : arr3) {
			System.out.print(i+",");
		}
		System.out.println();

		int[] arr4 = Arrays.copyOf(arr, 7);
		for(int i : arr4) {
			System.out.print(i+",");
		}
		System.out.println();
		
		int[] arr5 = Arrays.copyOfRange(arr, 2, 4); //2번부터 4-1인덱스까지
		for(int i : arr5) {
			System.out.print(i+",");
		}
		System.out.println();
		
		int[] arr6 = Arrays.copyOfRange(arr, 0, 7);	
		for(int i : arr6) {
			System.out.print(i+",");
		}
		System.out.println();
	}
}
더보기
더보기

실행결과

0,1,2,3,4,
0,1,2,
0,1,2,3,4,0,0,
2,3,
0,1,2,3,4,0,0,

- 열거타입

  : 한정된 값만 갖는 데이터 타입. 몇 개의 열거 상수 중 하나의 상수를 저장하는 데이터 타입

    ex) 월, 화, 수, 목, 금, 토, 일 / 봄, 여름, 가을, 겨울 ...

 

열거타입 선언

  1. 열거타입 이름으로 소스파일을 생성한다. (열거타입 이름: 각 단어의 첫문자는 대문자)

  2. 내용으로 열거타입을 선언한다.(이름은 소스파일명과 대소문자가 모두 일치해야함)

    public enum 열거타입이름 { ... }

  3. 열거 상수(대문자) 선언한다.(여러단어로 구성될경우 _로 연결)

    public enum Week { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, ... }
    public enum LoginResult { LOGIN_SUCCESS, LOGIN_FAILED

 

열거타입 변수

열거타입 변수 선언 열거상수 저장(단독사용 불가)
열거타입 변수; 열거타입 변수 = 열거타입.열거상수;
Week today; Week today = Week.SUNDAY;
리턴타입 메소드(매개변수) 설명  
String name() 열거 객체의 문자열을 리턴 Week today = Week.SUNDAY;
String name = today.name();
//"SUNDAY"를 리턴
int ordinal() 열거 객체의 순번(0부터 시작)을 리턴 Week today = Week.SUNDAY;
int ordinal = today.ordinal();
//MONDAY(0)~SUNDAY(6) // 6을 리턴
int compareTo() 열거 객체를 비교해서 순번차이를 리턴 Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;
int result1 = day1.compareTo(day2)
int result2 = day2.compareTo(day1)
//day2를 기준으로 상대적위치 -2 리턴
//day1을 기준으로 상대적위치 2리턴
열거타입 valueOf(String name) 주어진 문자열의 열거객체를 리턴 Week weekDay = Week.valueOf("SATURAY");
//외부로부터 문자열을 입력받아 열거객체로 변환할 때 유용하게 사용.
//weekDay변수는 Week.SATURDAY 열거객체를 참조
열거배열 values() 모든 열거객체들을 배열로 리턴 Week[] days = Week.values();
for(Week day : days){
  System.out.println(day);
}

 

 

 

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

[Java]반복문 - for, while, do~while  (0) 2022.01.05
[Java]조건문 - if, switch  (0) 2022.01.05
[Java]데이터 입출력  (0) 2022.01.04
[Java]연산자  (0) 2022.01.04
[Java]시작하기  (0) 2021.12.31