[Java] 스코프, 형변환, 배열, 메서드

스코프

1. 지역변수와 스코프

  • 지역변수 : 특정 지역(코드 블록 {})에서만 사용할 수 있는 변수
    • 자신이 선언된 코드 블록을 벗어나면 제거되기 때문에 접근할 수 없다.
  • 스코프(Scope) : 변수의 접근 가능한 범위

2. 스코프 존재 이유

  • 비효율적인 메모리 사용을 줄이기 위해
  • 코드 복잡성을 감소시키기 위해
    • 변수를 생각해야 하는 범위를 줄이면 유지보수하기 좋은 코드가 된다.

형변환

1. 자동 형변환

  • 작은 범위에서 큰 범위로 값을 대입하면 직접 형변환을 하지 않아도 형이 변경된다.
    • 예) intlongdouble
      • (double)로 적어주면 int 형이 double 형으로 변한다.
        int intValue = 10;
        double doubleValue;
        doubleValue = intValue; // 10.0
      
    • 자동 형변환 과정

        doubleValue = intValue
        doubleValue = (double) intValue //형 맞추기
        doubleValue = (double) 10 //변수 값 읽기
        doubleValue = 10.0 //형변환
      

2. 명시적 형변환

  • 큰 범위에서 작은 범위 대입 시 필요하다.
    • 예) doubleint
      • 명시적 형변환을 해주지 않으면 컴파일 오류가 발생한다.
      • doubleValue 안에 들어 있는 값은 1.5로 유지된다.
        double doubleValue = 1.5;
        int intValue = 0;
              
        //intValue = doubleValue; //컴파일 오류 발생
        intValue = (int) doubleValue; // 명시적 형변환
        System.out.println(intValue); // 1
      
  • 형변환과 오버플로우
    • maxIntOver은 int로 표현할 수 있는 범위를 넘는다.
      • int형은 2147483648L를 표현할 수 있는 방법이 없다.
      • 오버플로우로 인해 결국, int 의 가장 작은 숫자인 -214783648을 출력한다.
      • 오버플로우 : 기존 범위를 초과해서 표현하면 전혀 다른 숫자가 표현되는 현상
      • 오버플로우의 발생을 막기 위해 intValue의 타입을 intlong 으로 변경해서 사이즈를 늘려야 한다.
        long maxIntValue = 2147483647; //int 최고값
        long maxIntOver = 2147483648L; //int 최고값 + 1(초과)
        int intValue = 0;
              
        intValue = (int) maxIntValue; //형변환
        System.out.println("maxIntValue casting=" + intValue); //출력:2147483647
              
        intValue = (int) maxIntOver; //형변환
        System.out.println("maxIntOver casting=" + intValue); //출력:-2147483648
      

3. 연산과 형변환

1) 같은 타입끼리의 계산은 같은 타입의 결과를 낸다.<br>
2) 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 일어난다.
  • 예시
    • double + int는 double + double로 자동 형변환이 일어난다.

        double div3 = 3.0 / 2;
        System.out.println("div3 = " + div3); //1.5
      
    • 형변환 과정

        double div3 = 3.0 / 2; //double / int
        double div3 = 3.0 / (double) 2; //double / int이므로, double / double로 형변환이 발생한다.
        double div3 = 3.0 / 2.0; //double / double -> double이 된다.
        double div3 = 1.5;
      

배열

1. 배열의 선언과 생성

  • 배열 변수 선언
    • int[] 이면 정수를, double[]이면 실수를 담을 수 있다.

        int[] students;
      
  • 배열 생성
    • int형 변수 5개를 다룰 수 있는 배열을 생성한다.

        	students = new int[5]; //배열 생성
      
  • 배열 초기화
    • 배열 생성 시, 내부값을 자동으로 초기화한다.
    • 숫자는 0, boolean은 false, String은 null로 초기화된다.
  • 배열 참조값 보관
    image

    • 배열 생성시, 배열에 접근할 수 있는 참조값(주소)를 반환한다.
    • int[] students 변수는 생성된 배열의 참조값을 가지고 있게 된다.

2. 배열 사용

  • 배열에 값 대입
    • 배열의 위치를 나타내는 인덱스를 [] 에 넣어준다.
    • 배열의 인덱스는 0부터 시작한다.

        students[0] = 90;
        students[1] = 80;
      
  • 값 대입의 순서
    • 변수에 있는 참조값(x001)을 통해 실제 배열에 접근 → 인덱스를 사용해서 해당 위치의 요소에 접근 → 값 대입

3. 기본형 vs 참조형

  • 기본형(Primitive Type) : 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입
    • int, long, double, boolean
    • 기본형은 선언과 동시에 크기가 정해지기 때문에 크기를 동적으로 바꿀 수 없다.
    • 더 빠르고 메모리를 효율적으로 처리한다.
  • 참조형(Reference Type) : 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입
    • int[] students
    • 크기를 동적으로 할당할 수 있다. (동적 메모리 할당)
    • 더 복잡한 데이터 구조를 만들고 관리한다.

4. 1차원 배열 리팩토링

  • 1차원 배열의 편리한 초기화 : 배열 선언 시 new int[] 생략 가능
    • 자바가 내부에서 배열 요소의 크기를 보고 new int[5]를 사용해서 배열을 생성한다.

        int[] students = {90, 80, 70, 60, 50};
      

5. 2차원 배열

  • 2차원 배열은 행과 열로 구성된다.
    • [] 가 하나 추가되는 것을 제외하고는 1차원 배열과 사용법이 동일하다.
    • 행은 row, 열은 column

        int[][] arr = new int[2][3];
              
        arr[0][0] = 1; //0행, 0열
        arr[0][1] = 2; //0행, 1열
        arr[0][2] = 3; //0행, 2열
        arr[1][0] = 4; //1행, 0열
        arr[1][1] = 5; //1행, 1열
        arr[1][2] = 6; //1행, 2열
      

6. 2차원 배열 리팩토링

  • 2차원 배열의 편리한 초기화

      int[][] arr = {{1, 2, 3},{4, 5, 6}};
    
  • arr.length : 행의 길이
    • 2차원 배열에서는 {}, {} 2개의 배열 요소를 가진다.
  • arr[row].length : 열의 길이
    • arr[0].length 를 실행하면 3개의 요소를 가진다.

메서드

1. 메서드 사용

  • 메서드(Method) : 함수
  • 메서드 선언

      public static int add(int a, int b)
    
    • public : 다른 클래스에서 호출할 수 있는 메서드
    • static : 객체를 생성하지 않고 호출할 수 잇는 정적 메서드
    • int : 반환 타입 정의
    • add : 메서드의 이름 부여, 해당 이름으로 메서드를 호출 할 수 있다.
    • 메서드 선언에 사용되는 변수를 파라미터(parameter, 매개변수)라고 한다.
  • 메서드 본문
    • 메서드가 수행해야 하는 코드 블록
      {
      		System.out.println(a + "+" + b + " 연산 수행");
      		int sum = a + b;
      		return sum;
      }
    
    • return 문을 사용하여 메서드의 실행 결과를 반환한다.
    • 반환값이 없다면 반환 타입을 void로 설정해야 한다.
  • 메서드 호출
    • 메서드 이름에 입력 값을 전달한다.
      int sum1 = add(5, 10);
      int sum2 = add(15, 20);
    

2. 용어 정리

  • 인수(Argument) : 메서드에 넘기는 값
    • call("hello", 20) 에서 “hello”와 20
  • 매개변수(Parameter) : 메서드를 정의할 때 선언한 변수
    • int call(String str, int age) 에서 String str와 int age
    • 메서드 호출시 인수를 넘기면, 해당 인수가 매개변수에 대입된다.

3. 메서드 호출과 값 전달

  • 자바는 항상 변수의 값을 복사해서 대입한다.
  • 예시1

      public class MethodValue1 {
      		public static void main(String[] args) {
      				int num1 = 5;
      				System.out.println("1. changeNumber 호출 전, num1: " + num1);
      				changeNumber(num1);
      				System.out.println("4. changeNumber 호출 후, num1: " + num1);
      		}
        		
      		public static void changeNumber(int num2) {
      				System.out.println("2. changeNumber 변경 전, num2: " + num2);
      				num2 = num2 * 2;
      				System.out.println("3. changeNumber 변경 후, num2: " + num2);
      		}		
      }
    
    • 실행 결과
      • num1의 값을 복사해서 num2에 전달한다.
      • num2 값은 10으로 변경되지만, num2의 변경은 num1에 영향을 주지 않는다.
        1. changeNumber 호출 , num1: 5
        2. changeNumber 변경 , num2: 5
        3. changeNumber 변경 , num2: 10
        **4. changeNumber 호출 , num1: 5**
      
  • 예시2
    • 메서드의 호출 결과를 반환받아서 사용하면 값이 변경된다.
      public class MethodValue3 {
      		public static void main(String[] args) {
      				int num1 = 5;
      				System.out.println("changeNumber 호출 전, num1: " + num1); // 출력: 5
      				**num1** = changeNumber(num1);
      				System.out.println("changeNumber 호출 후, num1: " + num1); // 출력: 10
      		}
        		
      		public static int changeNumber(int num2) {
      				num2 = num2 * 2;return num2;
      		}
      }
    
    • 실행 결과

        changeNumber 호출 , num1: 5
        **changeNumber 호출 , num1: 10**
      

4. 메서드 오버로딩(Overloading)

  • 이름이 같고, 매개변수가 다른 메서드를 여러 개 정의하는 것
    • 반환타입이 다른 건 인정하지 않는다.

        public static void main(String[] args) {
        		myMethod(1, 1.2); // myMethod(int a, double b) 호출
        		myMethod(1.2, 2); // myMethod(double a, int b) 호출
        }
              
        public static void myMethod(int a, double b) {
        		System.out.println("int a, double b");
        }
              
        public static void myMethod(double a, int b) {
        		System.out.println("double a, int b");
        }
      
  • 본인의 타입에 최대한 맞는 메서드를 찾아서 실행하고, 그래도 없으면 형 변환이 가능한 타입의 메서드를 찾아서 실행한다.


김영한의 자바 입문을 참고하였습니다

© 2021. All rights reserved.

yaejinkong의 블로그