// 메서드 예
pubic static int add (int a, int b) {
System.out.println(a + " + " + b + " 연산 수행");
int sum = a + b;
return sum;
}
// 이 부분이 메서드다.
수학의 함수와 유사한데 함수의 값을 입력하면 어떤 연산을 처리한 다음 결과를 반환 한다.
메서드는 선언과 본문 으로 나눌 수 있다.
메서드에 넘기는 값과 매개변수 의 타입이 맞아야 하고 넘기는 순서도 맞아야 한다.
넘기는 값을 인자 (Argument) , 받는 값을 매개변수 (paramater)
호출 : call("hello", 20); // <- 인자 메서드 : int call(String str, int age); // <- 매개변수
메서드 선언
pubic static int add (int a, int b) // <- 이부분을 선언부라고 한다. // 메서드 이름, 반환타입, 매개변수(파라미터) 목록을 포함한다. // add -> 메서드 이름 // int -> 반환타입 // (int a, int b) -> 매개변수 (메서드 안에서만 사용 됨) // public -> 다른 클래스에서도 호출이 가능하다 (접근제어자에서 자세히) // static -> 객체를 생성하지 않고 바로 호출할 수있는 정적 메서드 (뒤에서 자세히)
메서드 본문
메서드가 수행해야 하는 코드 블록
메서드 호출 하는곳 에서는 선언부만 알고 본문은 모른다.
결과를 반환하려면 본문에 return 문을 사용 해야 한다.
반환타입과 return 타입이 동일 해야 한다.
{ System.out.println(a + " + " + b + " 연산 수행"); int sum = a + b; return sum; } // 메서드가 수행해야하는 코드 블록
메서드 호출
메서드를 호출 하려면 메서드 이름과 매개변수를 전달하면 된다.
int sum1 = add(5, 10); // 호출메서드명 (매개변수1, 매개변수2) int sum2 = add(15, 20); // 호출메서드명 (매개변수1, 매개변수2)
메서드 정의
메서드의 매개변수가 없는 경우
선언 : public static void printHeader() 와 같이 매개변수 를 비워두고 정의
호출 : printHeader(); 와 같이 인수를 비워두고 호출하면 된다.
메서드의 반환 타입이 없는 경우
선언 : public static void printHeader() 와 같이 반환 타입을 void 로 정의 하면 된다.
호출 : printHeader(); 와 같이 반환 타입이 없으므로 매서드만 호출 하고 값도 받지 않는다
반환 타입이 없는 경우의 메서드에는 return이 생략 가능하다.
반환 타입
반환타입이 존재하면 반드시 return값이 존재해야한다.
return 문을 만나는 순간 메서드를 탈출한다.
반환 타입이 있는 메서드를 호출 했을때 반환값을 사용하지 않아도 된다.
메서드 호출과 값 전달
자바는 항상 변수의 값을 복사해서 대입한다. (중요!!!)
메서드와 형변환
명시적 형변환
public class MethodCasting1 { public static void main(String[] args) { double number = 1.5; // printNumber(number); // <- 형변환을 하지 않아 주석을 풀면 오류가 발생한다. printNumber((int) number); // <- 명시적 형변환 사용 } public static void printNumber(int n) { System.out.println("숫자 : " + n); } }
자동 형변환
앞의 변수에서 배운 자동형변환 원칙이 동일하게 적용된다.
public class MethodCasting2 {
public static void main(String[] args) {
int number = 100;
printNumber(number); // <- 인자를 number로 넘겨도 큰곳으로
// 자동형변환으로 넘기기 때문에 문제없다.
}
public static void printNumber(double n) {
System.out.println("숫자 : " + n);
}
}
메서드 오버로딩
자바는 메서드의 이름뿐 아니라 매개변수 정보를 함께 사용하여 메서드를 구분한다. → 따라서 이름은 갖지만 매개변수가 다른 메서드를 정의 할 수있다.
add(int a, int b)
add(int a, int b, int c)
add(double a, double b)
// 이런식으로 이름은 갖지만 매개변수의 타입과 이름, 갯수로 구분이 가능하다.
오버로딩 → 같은 이름의 메서드를 여러개 정의했다
규칙 → 이름이 같고 매개변수의 타입및 순서가 다르면 오버로딩 가능 (단 반환타입은 인정하지 않는다.)
// 오버로딩 실패 케이스
int add(int a, int b)
double add(int a, int b)
메서드 시그니처 *
메서드 시그니처 = 메서드 이름 + 매개변수 타입 (순서)
자바에서 메서드를 구분 할 수 있는 고유한 식별자나 서명을 뜻한다.
메서드 사용의 장점
코드 재사용 : 필요한 기능을 캡슐화 시켜 필요할 때마다 해당 매서드를 호출하여 사용할 수 있다.
코드 가독성 : 이름이 부여된 메서드가 수행하는 작업을 나타내므로, 가독성이 좋아진다.
코드 유지 관리 : 코드를 쪼개서 관리하므로, 업데이트가 필요한경우 해당코드만 수정하여 관리 할 수 있다.
변수 : 선언한 위치에 따라 지역변수(Local Variable), 맴버변수 로 나뉜다. 지금까지 우리는 지역 변수로 배웠다.
지역변수 → 이름 그대로 특정 지역에서만 사용할 수 있는 변수, 지역을 벗어나면 사용할 수 없다. 여기서 말하는 지역은 변수가 선언된 코드 블럭( { } ) 중괄호 안을 의미 한다.
스코프의 존재 이유
변수를 선언한 시점부터 변수를 계속 사용할 수 있게 하면 좋겠다고 생각하지만 → 비효율적으로 메모리가 사용되고, 코드의 복잡성이 증가하게 된다.(스코프 범위 안의 변수가 사라지지 않는다면 변수를 새로 선언이나 사용할때에 주의를 기울여야하는 불편함이 생긴다.)
while 문과 for문을 비교해보면
// -> while문
public static void main(String[] args) {
int sum = 0;
int i = 1;
int endNum = 3;
while ( i <= endNum ) {
sum = sum + i;
System.out.println("i = " + i + " sum = " + sum);
i++;
}
}
// -> for문
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(sum);
}
}
// for 문과 while문은 같은 작동을 한다.
→ 해당 코드의 for 문과 while 문은 같은 작동을 하지만 while문의 scope 내에서 i 를 선언해 사용할 수 없어 main 에서 i 를 선언해줬다 그럼 생기는 문제가 다음 코드를 작성 해 줄 때에도 i 변수를 생각하면서 코드를 짜야하는 불편함이 생긴다. ⇒해당 코드는 for 문이 구조적으로 더 깔끔하다고 할 수 있다.
스코프 정리
변수는 꼭 필요한 범위로 한정하여 사용하자
좋은 프로그램은 무한한 자유보다 적절한 제약이 있는 프로그램이다.
형변환 → Casting
자동 형변환
작은 범위에서 큰 범위로는 당연히 값을 넣을 수 있다.
ex) int → long → double (가능)
큰 범위에서 작은 범위는 문제가 발생할 수 있다.
소수점 버림 (double → long, int)
오버 플로우 (long → int)
작은 → 큰 데이터 타입으로 변환될때에 자동으로 형태를 변환 시켜준다
ex ) int → double 할때에 int 타입의 데이터를 double 타입으로 자동으로 변환 시켜서 저장 시킨다.
package variable; // 패키지 위치 작성
public class Var1 { // 클래스 생성 규칙으로는 첫 글자 는 대문자
public static void main(String[] args) {
System.out.println(10);
System.out.println(10);
System.out.println(10);
}
}
위와 같이 10을 출력 하는 코드가 있는데 20으로 변경 하려면 하나하나 쳐줘야 한다.
이때에 변수 를 사용하여 쉽게 변경 할 수 있다.
변수
변수는 이름 그래돌 변할 수 있는 뜻
값을 저장하는 저장소 (데이터를 담는 그릇)
변수는 반복에서 읽을 수 있다.
package variable;
public class Var2 {
public static void main(String[] args) {
int a; // 변수 선언
a = 10; // 변수 초기화
System.out.println(a); // a 에 담긴 값을 출력
}
}
이렇게 사용하면 a 의 값만 변경 함으로 쉽게 변경이 가능하다.
변수 선언과 초기화
변수 선언하면 컴퓨터의 메모리 공간을 확보에 그곳에 데이터를 저장 한다.
변수의 이름을 통해 해당 메모리 공간에 접근한다.
변수는 꼭 초기화하고 사용해야 한다. → 이전에 무슨 값이 들어있는지 모르기 때문에 오류를 방지하기 위해 자바에서 변수를 초기화 하도록 강제 한다.
package variable;
public class Var5 {
public static void main(String[] args) {
int a; // 1. 변수 선언, 초기화 각각 따로
a = 1;
System.out.println(a);
int b = 2; // 2. 변수 선언과 초기화를 한번에
System.out.println(b);
int c = 3, d = 4; // 3. 여러 변수 선언과 초기화를 한번에
System.out.println(c);
System.out.println(d);
}
}
컴파일 에러는 좋은 에러, 런타임 에러는 안좋은 에러
변수 타입
int → 정수
double → 실수
boolean → 불리언 (참거짓)
char → 문자(문자 하나, 작은 따옴표로 감싼다.)
String → 문자열(큰 따옴표로 감싼다.)
각 변수는 자신의 알맞은 타입을 사용해야한다.
우리가 적는 값 들을 리터럴 이라고 한다.
변수타입 변수 = 리터럴
int a = 1;
이런형식
다양한 숫자 타입
정수
byte b = 127; // -128 ~ 127
short s = 32767; // -32,768 ~ 32,767
int i = 2147483647; // -21억 ~ 21억 정도
long l = 922337203L; // 엄청 긴 정수 가능 (이 범위 넘는 정도는 거의 없다.)
// 큰 수 일수록 메모리 공간을 많이 차지한다. → 대부분 int 사용한다.
실수
float f = 10.0f;
double d = 10.0; // float 보다 큰 범위
숫자 리터럴(값)의 범위
정수
int 값 범위만 작성이 가능하다.
21억 초과하는 값을 작성하려면 L(long)타입을 지정해줘야 한다.
실수
기본이 double 타입
float 타입 을 사용 하고 싶으면 f(float) 타입을 지정해줘야 한다. → 권장하지 않는다 실무에서는 double 위주로 사용한다.