변수는 선언한 위치에 따라 지역 변수, 멤버 변수(클래스 변수, 인스턴스 변수)와 같이 분류된다.
지역 변수는 이름 그대로 특정 지역에서만 사용할 수 있는 변수라는 뜻이다. 그 특정 지역을 벗어나면 사용할 수 없다.
여기서 말하는 지역이 바로 변수가 선언된 코드 블록( {} ) 이다. 지역 변수는 자신이 선언된 코드 블록( {} ) 안에서만 생
존하고, 자신이 선언된 코드 블록을 벗어나면 제거된다.
<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{}블록 내부에서도 m 에 접근가능- int x
=> if{} 블록안에서 선언
변수의 접근 가능한 범위를 스코프(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);
}
}
<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);
}
}
=> temp 는 if 조건이 만족할 때 임시로 잠깐 사용하는 변수이다. 그런데 임시 변수를 main()에 선언하기 되면 다음과 같은 문제가 발생한다.
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);
}
}
<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); //longValue = 10
doubleValue = intValue; // int -> double
System.out.println("doubleValue1 = " + doubleValue); //doubleValue1 =10.0
doubleValue = 20L; // long -> double
System.out.println("doubleValue2 = " + doubleValue); //doubleValue2 =20.0
}
}
<결과>
//intValue = 10
doubleValue = intValue
doubleValue = (double) intValue //형 맞추기
doubleValue = (double) 10 //변수 값 읽기
doubleValue = 10.0 //형변환
=> (double)과 같이 적어주면 int형이 double형으로 변한다.
큰 범위에서 작은 범위 대입은 명시적 형변환이 필요하다.
double-> int ?
<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
}
}
//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 => 오버플로우
}
}
<결과>
=> maxIntOver는 int로 표현 할 수 있는 가장 큰 숫자보다 1이 큼 -> 오버플로우 발생 -> intValue의 타입을 int에서 long 으로 변경
<Casting4.java>
package scope;
public class Casting4 {
public static void main(String[] args) {
int div1 = 3 / 2;
System.out.println("div1 = " + div1); //1
double div2 = 3 / 2;
System.out.println("div2 = " + div2); //1.0
double div3 = 3.0 / 2;
System.out.println("div3 = " + div3); //1.5
double div4 = (double) 3 / 2;
System.out.println("div4 = " + div4); //1.5
int a = 3;
int b = 2;
double result = (double) a / b;
System.out.println("result = " + result); //1.5
}
}
<결과>
- 같은 타입끼리의 계산은 같은 타입의 결과를 낸다.
- 서로 다른 타입의 계산은 큰 범위로 자동 형변환이 이루어진다.
int + long -> long + long
int + double -> double + double
int div1 = 3 / 2; //int / int
int div1 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = 3 / 2; //int / int
double div2 = 1; //int / int이므로 int타입으로 결과가 나온다.
double div2 = (double) 1; //int -> double에 대입해야 한다. 자동 형변환 발생
double div2 = 1.0; // 1(int) -> 1.0(double)로 형변환 되었다.
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;
double div4 = (double) 3 / 2; //명시적 형변환을 사용했다. (double) int / int
double div4 = (double) 3 / (double) 2; //double / int이므로, double / double로 형변환이 발생한다.
double div4 = 3.0 / 2.0; //double / double -> double이 된다.
double div4 = 1.5;
int -> long -> double