혼자 공부하는 자바 - 5장. 참조타입

youngtae·2023년 3월 25일
0

자바 이론

목록 보기
4/12
post-thumbnail

참조 타입과 참조변수

  • 배열, 열거, 클래스, 인터페이스 : 참조타입
  • 메모리 주소를 변수 안에 저장

JVM 메모리 사용영역

  • 메소드 영역

    • JVM이 시작할 때 생성되고 모든 스레드가 공유하는 영역
    • 메소드 영역에는 코드에서 사용되는 클래스들을 클래스 로더로 읽어 클래스별로 정적필드와 상수, 메소드 코드, 생성자 코드 등을 분류해서 저장
  • 힙 영역

    • 객체와 배열이 생성되는 영역
    • 여기에 생성된 객체와 배열은 JVM스택 영역의 변수나 다른 객체의 필요에서 참조
    • 참조하는 변수나 필드가 없으면 의미 없는 객체가 되기 때문에 쓰레기 수집기(garbage collector)를 실행시켜 자동으로 제거
  • JVM 스택영역

    • 메소드를 호출할 때마다 프레임을 추가하고 메소드가 종료되면 해당 프레임을 제거하는 동작 수행
    • 스택영역에는 배열의 주소값만 추가, 값은 힙 영역에

null

  • 참조 변수의 ==, ! = 연산은 참조 주소가 같은지를 판단
  • 주소가 같으면 같은 값
  • 힙 영역 객체 참조하지 않으면 null, refVar1 == null
  • null 인 참조 변수를 사용하려고 하면 NullPointerException 에러 발생

String

  • 자바는 문자열을 String 변수에 저장, 문자열 쓸때는 String 변수 선언
  • 큰따옴표로 감싼 문자열 리터럴 대입
  • 문자열은 객체로 생성되고 변수는 객체를 참조
String name;
name = "신용권";
String hobby = "자바";
  • new 연산자를 사용해서 직접 String 객체 생성가능
  • new 연산자는 힙 영역에 새로운 객체를 만들때 사용, 객체 생성 연산자 라고 함
String name1 = new String("신용권");
String name2 = new String("신용권");
//서로 다른 객체

배열

  • 각 데이터에 인덱스를 부여해놓은 자료구조
  • 같은 타입의 데이터만 저장 가능
  • 한번 생성된 배열은 길이를 늘리거나 줄일 수 없음
  • int[] intArray; 또는 int intArray[];
  • 배열 변수가 null값을 가진 상태에서 변수로 값을 읽거나 저장하게 되면 NullPointerException 발생
  • 배열 생성

    • String[] names = {”신용권”, “홍길동”, “김자바”};
    • names[0] = 신용권, names[1]=홍길동
    • 값 변경: names[1] = “홍삼원”;
    • 배열 변수를 이미 선언한 후에는 다른 실행문에서 중괄호를 사용한 배열 생성 x
    • 배열 변수 미리 선언 후 값이 나중에 결정되는 상황이면 new연산자 사용
    String[] names = null;
    names = new String[] {"신용권", "홍길동", "김자바"};
    
    //길이가 5인 배열 생성
    int[] intArray = new int[5]; //값은 기본값 0으로 초기화
    String[] names = new String[30]; //문자열이면 기본값 null로 초기
    
    • 타입별 배열의 초기값
  • 배열 길이

    • 배열변수.length; : 배열 길이 값

      int[] intArray = {10, 20, 30};
      int num = intArray.length;
      // length 필드는 읽기 전용, 값 변경 불가
      
  • 다차원 배열
    int[][] scores = new int[2][3];  // 2행 3열 배열
    
    int[][] scores = new int[2][];
    scores[0] = new int[2];
    scores[1] = new int[3];

    scores는 길이가 2인 배열 A참조,
    배열 A의 scores[0]은 다시 길이가 3인 배열 B참조
    scores[1]은 또 다른 길이가 3인 배열 C참조

    //값 목록을 알고 있을 때
    int[][] scores = {{95, 80}, {92, 96}};
    
    int score = scores[0][0]; //95
    int score = scores[1][1]; //96
  • 객체 참조하는 배열
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(strArray[0].equals(strArray[2])); // true 문자열이 동일
  • 베열 복사
    • for 문 이용한 배열 복사

      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] + ", ");  // 1, 2, 3, 0, 0
      		}
      	}
      }
    • arraycopy()로 배열 복사

      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 ( 타입변수: 배열) {  //루프 카운터 변수와 증감식 사용x
      	실행문;
      }
      
      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);
      
      	} 
      }

      확인문제

    • for문 이용해서 주어진 배열의 항목에서 최대값 구하기

      package CH5;
      
      public class ch5__2_4 {
          public static void main(String[] args) {
              int max = 0;
              int[] array = {1, 5, 3, 8, 2};
      
              for (int i=0; i< array.length; i++){
                  if (max < array[i]) {
                      max = array[i];
                  }
      
              }
              System.out.println("max : " + max);
          }
      } // max: 8
    • 중첩 for문을 이용해서 주어진 배열의 전체 항목의 합과 평균값 구하기

      package CH5;
      
      public class ch5_2_5 {
          public static void main(String[] args) {
              int[][] array = {
                      {95, 86},
                      {83, 92, 96},
                      {78, 83, 93, 87, 88}
              };
      
              int sum = 0;
              double avg = 0.0;
      
              int count = 0;
              for (int i=0; i< array.length; i++){
                  for (int j=0; j<array[i].length; j++){
                      sum += array[i][j];
                      count++;
                  }
              }
              avg = (double) sum/count;
              System.out.println("sum: " + sum);
              System.out.println("avg: " + avg);
          }
      }  // sum: 881, avg: 88.1
    • 학생 수와 각 학생들의 점수 입력받아서, 최고점수 및 평균점수 구하는 프로그램 작성

      package CH5;
      
      import java.util.Scanner;
      
      public class Exam06 {
      	public static void main(String[] args) {
      		boolean run = true;
      
      		int studentNum = 0;
      		int[] scores = null;
      
      		Scanner scanner = new Scanner(System.in);
      
      		while (run) {
      			System.out.println("--------------------------------------------------------------");
      			System.out.println("1.학생수 | 2. 점수입력 | 3. 점수리스트 | 4. 분석 | 5. 종료");
      			System.out.println("--------------------------------------------------------------");
      			System.out.print("선택> ");
      
      			int selectNo = Integer.parseInt(scanner.nextLine());
      
      			if (selectNo == 1) {
      				System.out.print("학생수> ");
      				studentNum = Integer.parseInt(scanner.nextLine());
      				scores = new int[studentNum];
      			} else if (selectNo == 2) {
      				for (int i = 0; i < scores.length; i++) {
      					System.out.print("scores[" + i + "]> ");
      					scores[i] = Integer.parseInt(scanner.nextLine());
      				}
      			} else if (selectNo == 3) {
      				for (int i = 0; i < scores.length; i++) {
      					System.out.println("scores[" + i + "]: " + scores[i]);
      				}
      			} else if (selectNo == 4) {
      				int max = 0;
      				int sum = 0;
      				double avg = 0;
      				for (int i = 0; i < scores.length; i++) {
      					max = (max < scores[i]) ? scores[i] : max;
      					sum += scores[i];
      				}
      				avg = (double) sum / studentNum;
      				System.out.println("최고 점수: " + max);
      				System.out.println("평균 점수: " + avg);
      			} else if (selectNo == 5) {
      				run = false;
      			}
      		}
      
      		System.out.println("프로그램 종료");
      	}
      }

열거 타입

  • 한정된 값인 열거상수 중에서 하나의 상수를 저장하는 타입
  • 열거타입 선언

    • 열거 타입 이름을 정하고 해당 이름으로 소스파일 .java 를 생성해야 함
    • 관레적으로 첫글자는 대문자 나머지 소문자
    • 소스파일 내용
      public enum 열거타입이름 {…}
         public enum Week { MON, TUE, WED, THU, FRI, SAT, SUN}
         // 열거타입이름은 소스파일 이름과 동일
         // 열거상수는 열거타입의 값, 모두 대문자로 작성
         // 여러단어라면 사이에 언더바 _ 로 연결
    • enum 파일 생성 - 상수 나열
    • null값도 저장 가능
    • 열거타입은 참조 타입, 열거 상수는 객체
      Week today = Week.SUN;
      // today에 Week.SUN이 참조하는 객체 주소 저장
      // today와 Week.SUN은 서로 같은 객체 참조
      today == Week.SUN;  //true
    • 캘린더 예제

      import java.util.Calendar;
      
      import sec03.exam01.Week;
      
      public class EnumWeekExample {
      	public static void main(String[] args) {
      		Week today = null;
      		
      		Calendar cal = Calendar.getInstance();
      		int week = cal.get(Calendar.DAY_OF_WEEK);
      		
      		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("열심히 자바 공부합니다.");
      		}
      	}
      } // 오늘 요일: WEDNESDAY
       // 열심히 자바 공부합니다.
profile
나의 개발기록

0개의 댓글