참조 자료형의 중요한 내용중 하나인 메소드에 대해서 알아보자.
메소드 종료조건?
- 모든 문장이 실행되었을 때,
- return을 만났을 때
- 예외가 발생했을 때
모든 문장이 실행된것은 말 그대로 메소드의 중괄호 안에 모든 문장이 실행되었고, 더이상 실행할 문장이 없으면 메소드가 종료된다는 것이다. return은 뭘까?
public class MethodTest {
public static void main(String[] args) {
}
public int returnIntMethod() {
int intValue = 100;
return intValue;
}
public String returnStrMethod(){
String strValue = "스트링";
return strValue;
}
public void returnVoidMehtod(){
System.out.println("void는 return이 필요하지 않아요!");
if(true) {
return;
}
System.out.println("얍!");
}
}
return은 메소드의 리턴타입에 따라서 그 쓰임새가 다르다.
- 리턴타입이 void가 아닌 메소드의 return.
- 리턴타입이 void가 아닌 메소드는 반드시 return을 써야하며, 이 경우 리턴은 메소드 리턴타입의 데이터를 자신을 호출한 곳으로 반환한다.
- 자바에서 모든 타입(기본자료형, 참조자료형)중 하나만 메소드의 리턴타입으로 넘겨줄 수 있다.
- 만약, 여러개를 넘겨주고 싶다면 DTO패턴을 쓴다.
- 리턴타입이 void인 메소드의 return.
- 보통의 경우 리턴타입이 void인 경우 return은 쓰지 않는다.
- 리턴타입 void인 메소드에서 return을 만나면 마치 반복문이나 switch문의 break처럼 해당 메소드를 더이상 실행하지 않고 종료한다.
static 메소드?
static메소드의 특징
- static 메소드는 객체를 생성하지 않고도, 메소드를 호출할수 있다.
- static 메소드는 클래스변수만 사용할 수 있다.
- 클래스변수 : 인스턴스 변수에 static 키워드가 붙은 변수이다. 클래스변수는 모든 객체에서 하나의 값을 바라본다.
static 블록과 instance 블록
public class BlockTest {
static int data = 0;
static {
System.out.println("static block{...}");
data = 3;
}
{
System.out.println("instance block{...}");
data = 1;
}
public BlockTest(){
System.out.println("default constructor...");
System.out.println(data);
}
}
public class Main {
public static void main(String[] args) {
BlockTest btest = new BlockTest();
BlockTest btest2 = new BlockTest();
}
}
// 결과
static block{...}
instance block{...}
default constructor...
1
instance block{...}
default constructor...
1
객체를 여러번 생성 하더라도 딱 한번만 호출되야하는 코드가 있다면 static 블록을 쓰자. static 블록은 객체가 생성되기 전에 한번만 호출되고, 그 이후에는 호출 할려고 해도 호출할 방법이 없다. 주로 클래스변수 초기화에 사용한다. block 안에서 클래스 변수 뿐만 아니라 static으로 선언된 메소드도 호출할 수 있다.
static 블록, instance 블록의 위치?
- 클래스 내부에 선언되어 있어야 한다.
- 메소드 내에서는 선언할 수 없다.
- 인스턴스 변수나 클래스 변수와 같이, 어떤 메소드나 생성자에 속하면 안된다.
인스턴스 블록은 인스턴스가 생성된 후 자동으로 실행하는 블록이다. 한 클래스 안에 여러 개의 인스턴스 블록을 넣을 수 있다. 주로 인스턴스 변수를 초기화할때 사용한다. 어떤 생성자가 호출되든 그 전에 공통으로 초기화시키고 싶은 작업이 있다면 인스턴스 블록에서 처리하면 된다. 스태틱 블록은 객체를 여러번 생성해도 단 한번만 호출되지만, 인스턴스블록은 객체를 생성할 때마다 호출된다는 차이가 있다.
메소드의 매개변수에 대한 고찰
매개변수로 전달하는 데이터의 타입에 따라서 주의해야할 사항이 있다. 기본자료형은 매개변수로 값을 전달(pass by value)하고 참조 자료형은 참조를 전달(pass by reference)한다.
Pass by value, Pass by reference
public class PassTest {
public void passByValue(int a, int b){
a = 10;
b = 5;
}
public void passByReference(int[] intArr){
intArr[0] = 10;
}
}
public class Main {
public static void main(String[] args) {
// 객체 생성
PassTest passTest = new PassTest();
int a= 1;
int b = 2;
System.out.println("호출전 a : " + a);
System.out.println("호출전 b : " + b);
// 기본자료형 int를 매개변수로 받음.
passTest.passByValue(a,b);
System.out.println("호출후 a : " + a);
System.out.println("호출후 b : " + b);
int[] intArr = new int[1];
intArr[0] = 3;
// 메소드 호출 전.
System.out.println("호출전 : " + intArr[0]);
// 참조자료형 int 배열을 매개변수로 받음.
passTest.passByReference(intArr);
// 메소드 호출 후.
System.out.println("호출후 : " + intArr[0]);
}
}
// 결과
호출전 a : 1
호출전 b : 2
호출후 a : 1
호출후 b : 2
호출전 : 3
호출후 : 10
위 코드를 보면 passByValue 메소드를 호출할때 기본자료형 int 값 두개(a,b)를 매개변수로 보낸다. 그리고 passByValue 메소드 안에서 해당 변수를 변경한다. 그래도 원래의 값(매개변수로 보낸 변수 값)은 변하지 않는다.
반면, passByReference 메소드는 참조자료형 int배열을 매개변수로 받아서, 배열의 첫번째 값을 바꾼다. 그러면, 원래 배열의 첫번째 값도 변경된다.
Pass by value
- 값만 전달한다.
- 건네 받은 값을 가지고 뭘하든 원래 값은 변하지 않음.
- 기본자료형은 Pass by value.
Pass by reference
- 값이 아닌 참조가 전달됨.
- 매개변수로 받은 참조 자료형 안에 있는 객체를 변경하면, 호출한 참조 자료형 안에 있는 객체는 호출된 메소드에서 변경한 대로 바뀐다.
- 참조 자료형은 Pass by reference.
매개변수를 지정하는 특별한 방법([타입]... [변수명])
매개변수의 개수가 정확히 정해져 있지 않은경우. 자바는 임의 개수의 매개변수를 넘겨주는 방법을 지원한다.
public void receiveManyParam(int... nums){
for(int tnum : nums) {
System.out.println(tnum);
}
}
위와 같이 지정해주면 아래와 같이 호출할 수 있다.
// 객체 생성
PassTest passTest = new PassTest();
passTest.receiveManyParam(1,2,3,4,5,6,7,8,9,10);
passTest.receiveManyParam(1,2,3,4,5);
passTest.receiveManyParam(1,2,3);
매개변수를 배열로 만들지 않고 임의의 개수만큼 매개변수를 사용할 수 있다. receiveManyParam 메소드는 배열을 받는 것 처럼 해당 매개변수를 사용할 수 있다.
이 방법을 사용할때 주의할 점은
- 하나의 메소드에서 한 번만 사용이 가능.
- 이 변수를 포함해 매개변수가 여러개 일 경우 꼭 이 변수를 매개변수 중 마지막에 써야 한다.
메소드 오버로딩?
앞서 배운 생성자는 이름은 같지만, 매개변수를 다르게 여러개 만들수 있었다. 메소드도 가능하다. 메소드의 이름은 같지만, 매개변수를 다르게 설정하는것을 메소드 오버로딩이라고 한다. 매개변수의 이름이 아니라 타입이 다르면 다른 메소드로 인식된다. 타입의 순서가 달라도 마찬가지다.
public class Overloading {
public void methodOverloading(String str){
System.out.println(str);
}
public void methodOverloading(int num){
System.out.println(num);
}
public void methodOverloading(String str, int num){
System.out.println(str + num);
}
public void methodOverloading(int num, String str){
System.out.println(str + num);
}
}
위 코드를 보면 메소드 이름은 모두 methodOverloading 이다. 그러나 받는 매개변수는 다르다. 주의할 것은 매개변수의 순서가 바뀌어도 다른 메소드로 인식한다.
왜 오버로딩을 만들었을까? 메소드 오버로딩을 사용하면, 메소드에 int만 넘겨도 나오고, String만 던져도 나온다. 이게 오버로딩의 이점이다. 같은 역할을 하는 메소드는 같은 이름을 가져야 한다는 모토로 사용한다.
'Java' 카테고리의 다른 글
[자바의 신] 접근제어자 (0) | 2020.10.02 |
---|---|
[자바의 신] 패키지 (0) | 2020.10.01 |
[자바의 신] 참조 자료형 - 생성자 (0) | 2020.09.21 |
[자바의 신] 변수 하나에 여러 개의 데이터를 담을 수 없을까? (0) | 2020.09.15 |
[자바의 신] 연산자? (0) | 2020.09.14 |