개발자(소스코드 작성) → 소스파일 → 컴파일러(컴파일) → 기계어 → 실행
1995년 Oak(오크)
를 새롭게 설계한 Java 발표
람다식(Lambda)
지원하여 코드 간결하게 작성 가능컴파일 언어: 소스코드를 한 번에 읽고 실행
스크립트 언어: 소스코드를 한 줄 씩 읽고 바로 실행
컴파일 언어 | 스크립트 언어 | |
---|---|---|
번역기 | 컴파일러 | 인터프리터 |
번역 단위 | 코드 전체 | 한 문장 |
실행속도 | 기계어 수준으로 빠름 | 느린 편 |
문법 | 엄격한 편 | 느슨한 편 |
종류 | C/C++, JAVA | JSP, PHP, Python, Ruby, JS |
java 소스 파일 생성 → (컴파일) → .class 바이트 코드
생성 → (실행) → JVM은 메모리 할당 → (메서드 영역에 클래스 로딩) → main 메서드 실행
public class ex01 {
// public: 예약어(키워드) 접근 지정자 -> 모든 클래스에서 접근 가능
// class: 예약어(키워드) 클래스임을 의미 -> 클래스 선언 시 사용
public static void main(String[] args) {
// static: 정적 변수/함수를 지정할 때
// 프로그램 시작 시 고정된 메모리 주소에 할당됨
// 프로그램 시작점이나 중요한 함수/변수에 사용함
System.out.println("Hello Java!");
// println: 콘솔에 문자열 출력하는 출력용함수 -> print line
}
}
public class ex02 {
public static void main(String[] args) {
// 한줄 주석문
/*
여러줄
주석문
*/
// 출력문
// + 연산자는 왼쪽이나 오른쪽에 문자열이 있으면 문자열 연결 연산자로 동작
// 둘 다 숫자이면 산술연산자로 동작
System.out.println("화면출력");
System.out.println("화면"+"출력"); // 문자열 연결
System.out.println("화면"+10*20); // 문자+숫자 -> 문자 // 화면200
System.out.println(10+20+"화면"); // 30화면
// 연산자 우선순위가 헷갈리면 소괄호로 묶어줌
System.out.println(10+(20+"화면"));
}
}
연산자 우선순위에의해 결정됨 → 보통 왼쪽에서 오른쪽으로
주석은 컴파일과정에서 무시됨 → 실행문만 바이트 코드로 번역
println vs print vs printf
// println vs print vs printf
// println: 문자열 한 줄 출력 + 줄바꿈
// print: 문자열 한 줄 출력, 줄바꿈 X
// printf: 형식화된 출력문
// \n: 줄바꿈 특수문자
System.out.println("한줄 출력 후 줄바꿈");
System.out.print("한줄 출력 후 줄바꿈 없음");
System.out.printf("%d\n", 30); // 10진수
System.out.printf("%o\n", 30); // 8진수
System.out.printf("%x\n", 30); // 16진수
// 지수형 출력 -> 실수를 넣어주어야함
System.out.printf("%e\n", 300.0);
// 다음과 같이 출력하시오.
// 1. "Coding is Good!"
System.out.println("Coding is Good!");
// 2. "Java"문자와 "Programming"문자를 +연결연산자로
// 연결해서 출력하시오.
System.out.println("Java"+"Programming");
// 3. 십진 정수 123을 printf를 이용하여 출력하시오.
System.out.printf("%d\n",123);
// 4. 십진 정수 123을 printf를 이용하여 "00123"으로 출력하시오.
System.out.printf("%05d\n",123);
// 5. 실수형 123.45f를 printf를 이용하여 "123.450"로 출력하시오.
System.out.printf("%.3f\n",123.45f);
자료형 변수이름 = 값;
→ ex) int num = 3;
_
, $
만 가능_
로 연결 → ex) final int MY_DATA;
❗️ 변수는 블록 단위로 스코프를 가짐
메모리 구조
class 영역, static 영역, final 영역, 메서드 영역 | Stack 영역(위치(번지) 저장) | Heap 영역(직접 접근 불가) |
---|
boolean(1byte)
(참/거짓), byte(1byte), short(2byte), int(4byte), long(8byte)
(정수), float(4byte), double(8byte)
(실수), char(2byte)
(문자, 정수)public class ex03 {
public static void main(String[] args) {
// 데이터 타입(자료형)
// 기본자료형 8개
// 정수형: int(4byte), long(8byte), short(2byte), byte(1byte)
int myInt = 10;
System.out.println(myInt);
long myLong = 20L; // L(l): long 리터럴로 초기화
System.out.println(myLong);
short myShort = 30;
System.out.println(myShort);
byte myByte = 40;
System.out.println(myByte);
// 실수형: float(4byte), double(8byte)
float myFloat = 6.12f; // f(F): float 리터럴로 초기화
// -> 리터럴 안적어주면 double로 인식하여 오류 발생
System.out.println(myFloat);
double myDouble = 3.14d; // d(D): double 리터럴로 초기화
System.out.println(myDouble);
// 논리형: boolean(1byte)
boolean myBoolean = true;
System.out.println(myBoolean);
// 문자형(내부적으로 숫자형): char(2byte)
char myChar = 'A';
char myChar2 = '가';
System.out.println(myChar);
System.out.println(myChar2);
System.out.println((int)myChar); // 65 -> 형변환
System.out.println((int)myChar2); // 44032
// 참조타입
// 문자열
String myString = "문자열ABC";
String myString2 = new String("문자열2");
System.out.println(myString);
System.out.println(myString2);
// 배열
// 클래스(객체)
// 열거형
}
}
리터럴 타입: 자료형 없이 값으로 입력하는 경우 값의 형태에따라 대표 자료형으로 자동 변환됨
자료형 값의 범위 순서: byte < short/char < int < long < float < double
float, double은 실수부, 지수부 나누므로 범위가 더 큼
타입 변환 방법
수동 형변환: 큰 범위에서 작은 범위로 넘어갈 때
형 변환 연산자 표기 → 수동 형변환
int a = (int)3.2; // 3
double b = (double)a; // 3.0
숫자 뒤 L(l), F(f) 표기
long a = (long)10;
long b = 10L;
float c = (float)5.8;
float d = 5.8f;
자동 형 변환: 작은 범위에서 큰 범위로 넘어갈 때
public class ex04 {
public static void main(String[] args) {
// 형변환 type casting
// 형변환 공식
// 1. 작은 정수형 -> 큰 정수형 (문제 X)
// 2. 큰 정수형 -> 작은 정수형 (문제 O, 표현 범위 벗어나면 값 잘림)
// 3. 실수형 -> 정수형 (값 잘림, 소수점 날아감)
// 4. 정수형 -> 실수형(문제 X)
// 자동 형변환: 대입(산술)연산자를 통해 자동으로 형변환 됨
// 1. 같은 타입끼리 연산될 때
// ex) int * int => int, long * long => long
int i = 10;
int j = 20;
int k = i * j;
// 2. 다른 타입끼리 연산될 때 => 더 큰 타입으로 변환
// ex) ing * long => long, long * float => float
long m = 10 * 20L;
// 3. 작은 타입에서 큰 타입으로 대입될 때 => 더 큰 타입으로 변경
long a = 10; // int
// 4. 큰 타입에서 작은 타입으로 대입될 때
int b=20L; // 형변환 안됨(Error 발생) -> 수동 형변환 해야함
// 수동(강제)형변환: 형변환 연산자(타입)을 통해 형변환 할 때
// 형변환 연산자 사용
// 주의할 점!! => 표현범위를 벗어나면 값 잘림(쓰레기 값)
// 작은 타입 = (작은 타입) 큰 타입;
int c = (int) 20L;
}
}
연습문제
//1. short형 변수 num1을 선언하고 10값을 넣어서 초기화 한다.
// int형 변수 num2를 선언하고 20값을 넣어서 초기화 한다.
// num1을 float형 변수 num3에 넣어서(대입) 자동형변환 시키자.
short num1 = 10;
int num2 = 20;
float num3 = num1;
System.out.println(num3);
//2. num2를 num1에 대입해서 강제 형변환 시킨 후 그 값을 출력하자.
num1 = (short) num2;
System.out.println(num1);
//3. num3와 num2값을 곱하기 연산(*)한 후 자동 형변환 한 값을 출력하자.
System.out.println(num3*num2);
String 클래스
ex) String str = “안녕”;
class 영역, static 영역, final 영역, 메서드 영역 | 100(str) Stack 영역 | “안녕”(100번지) Heap 영역 |
---|
new
키워드 이용
String 참조변수명 = new String(”문자열”);
문자열 리터럴 입력
String 참조변수명 = “문자열”;
객체 내 변경 불가능 → 값 변경시 새로운 객체 생성하여 작성
public class ex05 {
public static void main(String[] args) {
String str1 = new String("안녕");
String str2 = str1;
str1 = "안녕하세요";
}
}
class 영역, static 영역, final 영역, 메서드 영역 | 200(str1), 100(str2) Stack 영역 | “안녕”(100번지), “안녕하세요”(200번지) Heap 영역 |
---|
리터럴 바로 입력한 데이터는 문자열이 같은 경우 하나의 객체 공유
public class ex05 {
public static void main(String[] args) {
String str1 = new String("안녕"); // 새로운 객체 생성
String str2 = "안녕"; // 같은 내용의 리터럴 객체있는지 확인
String str3 = "안녕"; // 같은 내용의 리터럴 객체있는지 확인
// 있으면, 새로 생성 안하고 주솟값만 복사
String str4 = new String("안녕"); // 새로운 객체 생성
System.out.println(str1 == str2); // false
System.out.println(str2 == str3); // true
System.out.println(str3 == str4); // false
System.out.println(str4 == str1); // false
}
}
class 영역, static 영역, final 영역, 메서드 영역 | 100(str1), 200(str2), 200(str3), 300(str4) Stack 영역 | “안녕”(100번지), “안녕”(200번지), “안녕”(300번지) Heap 영역 |
---|
문자열 + 문자열 ⇒ 문자열 연결
문자열 + 기본 자료형 또는 기본 자료형 + 문자열 ⇒ 기본자료형을 문자열로 변환 + 문자열 연결
// 문자열 연결 연산자 +
// 산술 연산자 +
System.out.println("한글" + "만세"); // 한글만세
System.out.println("한글" + 10); // 한글10
System.out.println(10 + "한글"); // 10한글
System.out.println(10 + 20); // 30
System.out.println("한글"+10+20); // 한글1020 // 연산자 우선순위 좌 => 우
System.out.println(10+20+"한글"); // 30한글
기본 자료형 ↔ 문자열
// 기본자료형 => 문자열형으로 변환
String str = **String.valueOf**(10);
System.out.println(str);
// 문자열형 => 정수형
int num = **Integer.parseInt**("10");
System.out.println(num);
String 주요 메서드
import java.lang.reflect.Array;
import java.util.Arrays;
public class ex06 {
public static void main(String[] args) {
// 문자열 관련 함수들
// length(): 문자열 길이
String str1 = "Hello Java!";
String str2 = "안녕하세요! 반갑습니다.";
System.out.println(str1.length()); // 11
System.out.println(str2.length()); // 13
System.out.println();
// charAt(index): 해당 인덱스에 있는 문자 반환 -> 문자 한 글자만 가져옴
char c1 = str1.charAt(0); // 0부터 시작인덱스, 음수는 -1부터 시작(뒤부터)
System.out.println(c1); // H
char c2 = str1.charAt(1);
System.out.println(c2); // e
// indexOf(문자/문자열[,탐색 시작 위치]): 해당 문자/문자열의 위치(인덱스) 반환
// lastIndexOf(문자/문자열[,탐색 시작 위치]): 마지막 문자(열)의 위치 반환
// 만약, 존재하지 않는다면 -1 반환
System.out.println(str1.indexOf("Java")); // 6
System.out.println(str1.lastIndexOf("a")); // 9
String str3 = "Java Study";
// toUpperCase(): 대문자로 바꾸기
System.out.println(str3.toUpperCase()); // JAVA STUDY
// toLowerCase(): 소문자로 바꾸기
System.out.println(str3.toLowerCase()); // java study
// 문자열로 검색시 전부 소문자로 바꿔서 검색
System.out.println(str3.toLowerCase().indexOf("java")); // 0
// replace(기존 문자/문자열, 바꿀 문자/문자열): 문자열 치환하기
System.out.println(str3.replace("Study", "공부")); // Java 공부
// substring(시작인덱스, 끝인덱스): 문자열 일부 가져오기 -> 시작인덱스 ~ 끝인덱스-1
System.out.println(str3.substring(0, 5)); // Java
// subsplit(구분기준 문자/문자열[, limit]): 문자열 분리하여 문자열 배열로 가져오기
// limit: 분할 최대 개수
String[] strArray = "abc/def-ghi jkl".split("/|-| ");
// |: or(또는) 위에 같은 경우는 / or - or 공백
System.out.println(strArray.length); // 4
// Arrays.toString(배열): 배열을 문자열로 변환
System.out.println(strArray); // [Ljava.lang.String;@36baf30c -> 주솟값 출력됨
System.out.println(Arrays.toString(strArray)); // [abc, def, ghi, jkl]
// trim(): 문자열의 처음과 끝의 공백만 제거 -> 가운데 공백은 제거 안함
System.out.println(" abc ".trim()); // abc
System.out.println(" abc def ".trim()); // abc def
// 모든 공백을 제거 -> replaceAll(기존 문자/문자열, 바꿀 문자/문자열) 이용
System.out.println(" abc def ".replaceAll(" ", "")); // abcdef
// concat(합칠 문자열): 문자열 연결 함수
System.out.println("abc".concat("123")); // abc123
// contains(확인할 문자열): 문자열을 포함하는지 true/false 반환하는 함수
System.out.println("abc123".contains("123")); // true
// equals(비교할 문자열): 문자열 내용 비교하기
String str4 = "Java";
String str5 = "java";
// 주솟값 정수 비교
System.out.println(str4 == str5); // false -> 주솟값이 다름
// 내용 비교
System.out.println(str4.equals(str5)); // false
}
}
연습문제
String str5 = "java";
String str6 = "Web Programming is funny~";
String str7 = " Test Trim String ";
//1. "funny"의 시작 인덱스를 출력하시오.
System.out.println(str6.indexOf("funny"));
//2. str6를 모두 대문자로 출력하시오.
System.out.println(str6.toUpperCase());
//3. str6를 모두 소문자로 ~
System.out.println(str6.toLowerCase());
//4. str5와 str6을 concat함수로 연결하여 출력하시오.
System.out.println(str5.concat(str6));
//5. str7의 시작과 끝 공백만 제거하여 출력하시오.
System.out.println(str7.trim());
//6. str7의 모든 공백을 *로 치환하여 출력하시오.
System.out.println(str7.replaceAll(" ","*"));
//7. str6은 "web"문자열을 포함하고 있는지? (대소문자 안가림)
// true/false로 출력하시오.
System.out.println(str6.toLowerCase().contains("web"));
//8. str6을 문자열 배열로 만들고, "Web"와 "funny~"만 출력하시오.
String[] strArray = str6.split(" ");
System.out.println(strArray[0]+" "+strArray[3]);
[연산자 종류 정리]
public class ex07 {
public static void main(String[] args) {
// 연산자
// 연산자 우선순위
// 1. 단항 연산자: ++, --, !, (타입), ~(비트반전), =, +=(복합대입연산자)
// : 오른쪽이 먼저 연산됨
int i = 10;
int j = 20;
int k = i = j;
System.out.println(k); // 20
// 2. 다항 연산자: 이항, 삼항 연산자
// : 왼쪽이 먼저 연산됨
int m = i + j + k; // m = 20 + 20 + 20
System.out.println(m); // 60
int n = i + j / k * 10 / 7 + 10; // 난독성 코드
// Tip! 연산자 우선순위를 '소괄호'로 구분해서 코드를 심플하게 한다.
// 형변환 연산자
float f = (float) 10;
// 나눗셈을 해서 몫과 나머지가 나온다.
// 10을 3으로 나누면 몫 3, 나머지 1
// 이때 몫은 / 연산자로 구하고, 나머지는 % 연산자로 구한다.
// 연산자의 종류 - 이항연산자(산비논대)
// 단항: ++, --, !(논리반전), (타입), ~(비트반전) 우선순위가 가장 높다.
// 산술: +, -, *, /, % <<, >>, >>> (비트단위 이동연산자)
// 비교: <, >, <=, >=, !=, ==, instanceof(객체비교연산자)
// 논리: &&, || &, |, ^ (비트 단위 논리연산자)
// 삼항: ? :
// 대입: =, 복합대입(+=, -=, *=, /=, %= ...) 우선순위가 가장 낮다.
// 비교, 논리연산자는 결과값이 항상 true/false 로 나옴.
// 조건절에 주로 사용됨.
// 나머지는 결과값이 다 값으로 나옴.
}
}
[단항 연산자]
public class ex08 {
public static void main(String[] args) {
// 단항: ++, --, !(논리반전), (타입), ~(비트반전)
int i = 10;
i++; // i = i + 1
System.out.println(i); // 11
i--; // i = i - 1
System.out.println(i); // 10
boolean b = true;
System.out.println(!b); // false
System.out.println(!!b); // true -> 근데 실무에서 이런코드 좋아하지 않음
int j = 20;
short s = (short) j; // 값의 표현범위가 작은 타입 <= 큰 타입: 강제 형변환 필요
int k = 10; // 32bit 000000....1010
int m = ~k; // 32bit 111111....0101
System.out.println(Integer.toBinaryString(k)); // 1010
System.out.printf("%032d\n", Integer.parseInt(Integer.toBinaryString(k))); // 00000000000000000000000000001010
System.out.println(Integer.toBinaryString(m)); // 11111111111111111111111111110101
}
}
[산술 연산자]
public class ex09 {
public static void main(String[] args) {
// 산술: +, -, *, /, % <<, >>, >>> (비트단위 이동연산자)
int i = 10;
int j = 3;
System.out.println(i + j);
System.out.println(i - j);
System.out.println(i * j);
System.out.println(i / j); // 나눗셈의 몫
System.out.println(i % j); // 나눗셈의 나머지
// 나머지 연산자 %
int k = 123;
// 연습문제 = 나머지연산자를 이용하여
// 1. 일의 자리수 3을 출력하시오.
System.out.println(k % 10);
// 2. 십의 자리수 2를 출력하시오.
System.out.println(k % 100 / 10);
// 3. 백의 자리수 1을 출력하시오.
System.out.println(k / 100);
double d = 3.567;
// 4. 소숫점 첫째자리를 출력하시오. // 5
System.out.println((int) (d * 10 % 10));
// ✓ 소수점 없애기
// (1). Math.floor
// (2). (int) 형 변환 연산자
// 5. 소숫점 첫째자리에서 반올림하여 출력하시오. // 4.0
System.out.printf("%.1f\n", (float) Math.round(d));
// Math.round(): 소수점 첫째자리 반올림
// (1) 0.5 더해준다.
// (2) (int)형변환 연산자로 소수점을 날린다.
// (3) 결과적으로 반올림이 된다.
// 예) 3.49 => 3 (1) +0.5 (2) (int)3.99
// 3.5 => 4 (1) +0.5 (2) (int)4.0
// 3.99 => 4 (1) +0.5 (2) (int)4.49
// 6. 소숫점 둘째자리에서 반올림하여 출력하시오. // 3.6
System.out.println(Math.round(d * 10) / 10.0);
System.out.printf("%.1f", d);
}
}
[비트단위 이동 연산자]
public class ex10 {
public static void main(String[] args) {
// <<, >>, >>> (비트단위 이동연산자)
int k = 10;
String binaryString =
String.format("%32s", Integer.toBinaryString(k)).replace(" ", "0");
System.out.println(binaryString); // 00000000000000000000000000001010
// 최상위 비트(MSB) 0이면 양수, 1이면 음수
// 컴퓨터가 음수를 만드는 방법
// 2의 보수 = 1의 보수 + 1
// 1의 보수는 0->1, 1->0 변환
// +1 => -1로 만드는 과정
// 0000....0001 => 1111....1110(1의보수) => 1111....1111(2의보수)
// +1 : 00000...0001
// -1 : 10000...0001 사람이 생각하기 쉬운 음수
// -1 : 11111...1111 2의보수
// <<: 왼쪽으로 비트이동 *2의 효과
// : LSB 는 0이 들어옴.
// : MSB 는 0이면 0, 1이면 1로 지켜짐
int i = 1; // 0000...0001
System.out.println(i << 1); // 0000...0010 // 2
System.out.println(i << 2); // 0000...0100 // 4
System.out.println(-1 << 1); // -2
System.out.println(-1 << 2); // -4
// >>: 오른쪽으로 비트이동 /2의 효과
// : 양수이면 MSB 가 0이 들어옴
// : 음수이면 MSB 가 1이 들어옴
System.out.println(1 >> 1);
System.out.println(-1 >> 1);
// >>>: 오른쪽으로 비트이동하되 논리적 이동
// : 양수든 음수든 0이 들어옴.
// 0 000...0001
// 0 000...0000
System.out.println(1 >>> 1); // 0
// 1 111...1111
// 0 111...1111 논리적으로 이동한 결과 0이 들어옴.
System.out.println(-1 >>> 1);
}
}
[비교, 논리 연산자]
public class ch11 {
public static void main(String[] args) {
// 비교: <, >, <=, >=, !=, ==, instanceof(객체비교연산자)
// A > B: A가 B보다 큰가? true/false
// A < B: A가 B보다 작은가?
// A == B: A와 B가 같은가?
// A != B: A와 B는 같지않은가?
// A >= B: A가 B보다 크거나(OR) 같은가? -> A > B || A == B
// A <= B: A가 B보다 작거나(OR) 같은가? -> A < B || A == B
// 논리: &&, || &, |, ^ (비트 단위 논리연산자)
// AND &&: ~이고, ~이면서
// OR ||: ~이거나, 또는, ~중의 하나
// NOT !: ~아니다.
// T && T => T 둘다 참이면 참
// T && F => F
// F && T => F
// F && F => F
// T || T => T
// T || F => T
// F || T => T
// F || F => F 둘다 거짓이면 거짓
// !T => F
// !F => T
// XOR ^: 비트 단위 연산자
// 1 ^ 1 => 0
// 1 ^ 0 => 1 서로 값이 다르면 1
// 0 ^ 1 => 1
// 0 ^ 0 => 0
// 연습문제
// 1. 10은 2의 배수인지를 true/false 로 출력하시오.
System.out.println(10 % 2 == 0);
// 2. 10은 4의 배수이면서 2의 배수인지를 true/false 로 출력하시오.
System.out.println(10 % 4 == 0 && 10 % 2 == 0);
// 3. 15는 10이상이면서 20미만인지
System.out.println(15 >= 10 && 15 < 20);
// 4. 3은 9의 약수이면서 15의 약수인지를
System.out.println(9 % 3 == 0 && 15 % 3 == 0);
}
}
[삼항연산자]
public class ch12 {
public static void main(String[] args) {
// 삼항연산자: ? : 물음표 연산자
// 패턴: (조건절) ? A값 : B값
int i = 10 < 20 ? 10 : 20;
System.out.println(i); // 10
// 삼항연산자는 중복해서 쓰지 않기를 권장함
int j = (10 < 20) ? (20 < 30) ? 20 : 30 : 40;
System.out.println(j); // 20
// 대입연산자
// A = B: B값을 A에 덮어쓰기 한다.
// 값의 전달 방향이 오른쪽에서 왼쪽
// 단항연산자이므로 연산순서도 오른쪽에서 왼쪽으로
int i1 = 10;
int j1 = 20;
int k1 = 30;
i1 = j1 = k1 = 40;
; // 40 40 40
// 복합대입연산자
// A += B: A = A + B
// A -= B: A = A - B
// A *= B: A = A * B
// A /= B: A = A / B
// 연습문제
// 다음 코드를 삼항 연산자로 변경하시오.
int a = 10;
String result;
if (a > 0) {
result = "정상";
} else {
result = "비정상";
}
// 바꾼 코드
result = a > 0 ? "정상" : "비정상";
System.out.println(result);
}
}
import java.util.Scanner;
public class ex13 {
public static void main(String[] args) {
// Scanner 클래스 함수들
// nextLine(): 문자열을 입력받되 엔터칠때까지(공백 포함)
// next(): 문자열의 공백까지 입력받음
// nextInt(): 문자열을 받아서 정수로 변환해줌
// nextFloat(): 문자열을 받아서 실수로 변환해줌
// nextDouble(): 문자열을 받아서 실수로 변환해줌
Scanner scan = new Scanner(System.in);
String str1 = scan.nextLine();
System.out.println(str1);
String str2 = scan.next();
System.out.println(str2);
// java.util.InputMismatchException
// next()함수에 저장된 버퍼메모리가 정리되지 않아서 에러 발생!!
// 해결방안: nextLine()함수를 한번 실행해준다.
scan.nextLine();
int num1 = scan.nextInt();
System.out.println(num1);
scan.close(); // scan 객체가 사용중인 메모리 정리
}
}