ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이것이 자바다 | 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. 배열 복사

     

    배열을 한 번 생성하면 크기를 변경할 수 없기 때문에 더 많은 저장공간이 필요하다면 보다 큰 배열을 새로 만들고 이전 배열로부터 항목 값들을 복사해야 한다. 

     

    배열 간의 항목 값들을 복사하는 방법

    1. for문 사용
    2. 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. 열거 타입

     

    1. 열거 타입 이름으로 소스파일(.java)생성
    2. 열거 타입의 이름은 관례적으로 첫 문자가 대문자
    3. 열거 상수(열거 타입의 값)은 관례적으로 모두 대문자

          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("열심히 자바 공부를 합시다.");
    		}
    	}
    }
Designed by Tistory.