6-1. 스코프1 - 지역 변수와 스코프
변수
선언한 위치에 따라 분류됨
지역변수, 멤버 변수(클래스 변수, 인스턴스 변수)
지역 변수 (=로컬 변수 Local Variable)
특정 지역에서만 사용할 수 있는 변수
이 지역은 변수가 선언된 코드 블록{ }이다.
Scope1.java
package scope;
public class Scope1 {
public static void main(String[] args) {
int m = 10; // m 생존 시작
if (true) {
int x = 20; // x 생존 시작
System.out.println("if m = " + m); // 블록 내부에서 블록 외부는 접근 가능
System.out.println("if x = " + x);
} // x 생존 종료
// System.out.println("main x = " + x); // 오류, 변수 x에 접근 불가
System.out.println("main m = " + m);
} // m 생존 종료
}
- int m은 main{ } 의 코드 블록 안에 선언되어 if{ } 블록 내부에서도 접근 가능하다
- int x는 if{ } 블록 안에서 선언된다. if{ } 블록이 끝나면, x 는 제거 되기에 더는 x 에 접근할 수 없다.
스코프 (Scope)
변수의 접근 가능한 범위
Scope2.java
package scope;
public class Scope2 {
public static void main(String[] args) {
int m = 10;
for (int i = 0; i < 2; i++) { // 블록 내부, for문 내
System.out.println("for m = " + m); // 블록 내부에서 외부는 접근 가능
System.out.println("for i = " + i);
} // i 생존 종료
// System.out.println("main i = " + i); // 오류, i에 접근 불가
System.out.println("main m = " + m);
}
}
6-2. 스코프2 - 스코프 존재 이유
Scope3_1.java
package scope;
public class Scope3_1 {
public static void main(String[] args) {
int m = 10;
int temp = 0;
if (m > 0) {
temp = m * 2;
System.out.println("temp = " + temp);
}
System.out.println("m = " + m);
}
}
- 조건이 맞으면 변수 m의 값을 2배 증가해 출력하는 코드
- 2배 증가한 값을 저장하기 위해 임시 변수 temp 사용
- 좋은 코드가 아닌 이유
- 비효율적인 메모리 사용: 임시 변수 temp는 if 코드 블록에서만 필요. 하지만 main{ } 코드 블록에 선언되어 있어 main{ } 코드 블록이 종료될 때까지 유지되어 메모리를 낭비된다.
- 코드 복잡성 증가: main{ } 어디서나 temp를 여전히 접근할 수 있다. 누군가 이 코드를 유지보수 할 때 m 은 물론이고 temp 까지 계속 신경써야 한다.
Scope3_2.java (temp 변수 선언 위치 변경)
package scope;
public class Scope3_2 {
public static void main(String[] args) {
int m = 10;
if (m > 0) {
int temp = m * 2;
System.out.println("temp = " + temp);
}
System.out.println("m = " + m);
}
}
while문 vs for문 - 스코프 관점
더보기
public class While2_3 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
int endNum = 3;
while (i <= endNum) {
sum = sum + 1;
System.out.println("i=" + i + " sum=" + sum);
i++;
}
}
}
public class For2 {
public static void main(String[] args) {
int sum = 0;
int endNum = 3;
for (int i = 1; i <= endNum; i++) {
sum = sum + i;
System.out.println("i=" + i + " sum=" + sum);
}
}
}
- while문의 경우 변수 i 의 스코프가 main() 메서드 전체가 된다
- 반면, for문은 변수 i 의 스코프가 for문 안으로 한정되어 스코프의 범위를 제한한다.
- 메모리 사용과 유지보수 관점에서 for문을 사용하는 것이 더 좋다.
6-3. 형변환1 - 자동 형변환
형변환(casting)
작은 범위에서 큰 범위로 값을 넣을 수 있다.
ex) int -> long -> double
큰 범위에서 작은 범위는 문제가 발생할 수 있다.
소수점 버림, 오버플로우
작은 범위에서 큰 범위로 대입은 자바 언어에서 허용한다. => 자동 형변환
Casting1.java
package scope;
public class Casting1 {
public static void main(String[] args) {
int intValue = 10;
long longValue;
double doubleValue;
longValue = intValue; // int -> long
System.out.println("longValue = " + longValue);
doubleValue = intValue; // int -> double
System.out.println("doubleValue1 = " + doubleValue);
doubleValue = 20L; // long -> double
System.out.println("doubleValue2 = " + doubleValue);
}
}
자동 형변환 (= 묵시적 형변환) 과정
자동 형변환 과정
// intValue = 10
doubleValue = intValue
doubleValue = (double) intValue // 형 맞추기
doubleValue = (double) 10 // 변수 값 읽기
doubleValue = 10.0 // 형변환
6-4. 형변환2 - 명시적 형변환
큰 범위에서 작은 범위 대입은 명시적 형변환이 필요
Casting2.java
package scope;
public class Casting2 {
public static void main(String[] args) {
double doubleValue = 1.5;
int intValue = 0;
// intValue = doubleValue; // 컴파일 오류 발생
intValue = (int) doubleValue; // 형변환
System.out.println(intValue); // 출력:1
}
}
- 숫자가 손실되는 문제가 발생할 수 있어 컴파일 오류를 발생시킨다. ex) 은행 프로그램 이자 지급 코드
명시적 형변환
형변환은 다음과 같이 변경하고 싶은 데이터 타입을 (int) 와 같이 괄호를 사용해서 명시적으로 입력
intValue = (int) doubleValue; // 형변환
개발자가 직접 형변환 코드를 입력한다
명시적 형변환 과정
// doubleValue = 1.5
intValue = (int) doubleValue;
intValue = (int) 1.5; // doubleValue에 있는 값을 읽는다.
intValue = 1; // (int)로 형변환 한다. intValue에 int형인 숫자 1을 대입한다.
Casting3.java (형변환과 오버플로우)
package scope;
public class Casting3 {
public static void main(String[] args) {
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
}
}
- 보통 오버플로우가 발생하면 마치 시계가 한바퀴 돈 것 처럼 다시 처음부터 시작한다.
- 참고로 -2147483648 숫자는 int 의 가장 작은 숫자이다.
- 오버플로우 발생 자체가 문제다. => 변수타입을 long으로 변경해서 예방
6-5. 계산과 형변환
Casting4.java
package scope;
public class Casting4 {
public static void main(String[] args) {
int div1 = 3 / 2; // int/int
System.out.println("div1 = " + div1); // 1
double div2 = 3 / 2; // int/int
System.out.println("div2 = " + div2); // 1.0
double div3 = 3.0 / 2; // double/int -> double/double
System.out.println("div3 = " + div3); // 1.5
double div4 = (double) 3 / 2; // double/int -> double/double
System.out.println("div4 = " + div4); // 1.5
int a = 3;
int b = 2;
double result = (double) a / b; // a를 double로 casting
System.out.println("result = " + result); // 1.5
}
}
- 같은 타입끼리의 계산은 같은 타입의 결과를 낸다.
- int + int 는 int 를, double + double 은 double 의 결과가 나온다.
- 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 일어난다.
- int + long 은 long + long 으로 자동 형변환이 일어난다.
- int + double 은 double + double 로 자동 형변환이 일어난다.
'IT > 김영한의JAVA입문_inFlearn' 카테고리의 다른 글
7. 훈련 - Scanner / Scanner 기본 예제 / Scanner 반복 예제 / 문제와 풀이1~4 (2) | 2024.12.27 |
---|---|
5. 반복문 - while문 / do-while문 / break, continue / for문 / 중첩 반복문 / 문제와 풀이1~2 (1) | 2024.12.26 |
4. 조건문 - if문1~3 / switch문 / 삼항 연산자 / 문제와 풀이1~2 (1) | 2024.12.24 |
3. 연산자 - 산술 연산자 / 문자열 더하기 / 연산자 우선순위 / 증감 연산자 / 비교 연산자 / 논리 연산자 / 대입 연산자 (1) | 2024.12.19 |
2. 변수 - 변수 시작 / 변수 값 변경 / 선언과 초기화 / 변수 타입 / 명명 규칙 / 문제와 풀이 (1) | 2024.12.04 |