2011년 1월 5일 수요일

접근제한(1)- 우리는 메소드를 정확히 이해하는가?

객체지향에서에서 객체가 가지는 데이터는 좀 특별한 의미를 가지게 된다.

대게의 경우 인스턴스 변수의 성격은 다음과 같다.

'객체의 메소드의 결과를 누적하기 위해서 사용하는 경우'
'객체의 메소드들 간에 데이터를 공유하기 위해서 사용하는 경우'
'객체의 메소드가 실행될 때 현재의 데이터를 기준으로 해서 분기하는 경우'

즉 객체지향에서는 데이터는 메소드의 결과라는 것이지... 데이터 그 자체는 보관의 대상일 뿐이다.

다음의 코드를 생각해 보자.



public class AccessTest {

private int result;
public int getResult(){
return result;
}
}

이 코드를 보면 마치 getResult( ) 라는 메소드를 실행하면 실제로 result변수를 반환해 주는 것처럼 오해하기 딱 좋은 코드다. 

그럼 정말로 result라는 변수를 반환해 주는 것일까? 
불행하게도 자바는 현재 변수의 정확한 메모리 주소를 알아낼 수 있는 방법을 제공하지는 않는다. 뭐.. 로직을 작성할 때 가능하면 헷갈리게 하고 싶지 않았던 설계자의 의도이니 할 말은 없지 않은가? 

메소드의 코드를 보면 재밌는 것은 메소드의 리턴 타입에 int라는 타입이 사용되었다는 점이다. 

이 점이 뭐가 특이한가?라고 생각할 수도 있겠지만, 조금만 더 생각해보면 이것이 바로 메소드의 리턴타입의 비밀일 지도 모른다. 

메소드는 실행되기 위해서는 메소드가 실행되는 Stack에 들어가야만 실행이 되는 구조이다. 그렇다면 이 실행을 하기 위해서 만들어지는 결과물 역시 어떤 메모리 공간을 차지 하지 않을까? 

우리가 변수의 선언 앞에 int i; 라고 선언하는 것을 생각해 보자. 
이때 알고 있는 사실은 메모리상에 int의 공간만큼 메모리 공간이 할당된다는 것이다. 
그렇다면 메소드의 리턴 타입도 같은 원리가 아닐까?

즉 메소드의 리턴 타입은 '실행된 결과를 메모리 공간에 담기위한 설정'이라는 것이다. 
위의 코드를 실해하면 메소드가 실행된 결과를 위해서 메모리 공간이 하나 할당 되고, 실행되는 결과물은 변수의 연산처럼 메모리 공간을 사용하게 될 것이다. 

메소드의 리턴타입이란 참 재밌게도 연산자와 달리 그 실행 결과를 특정 변수에 담거나 접근해서 소비하는 일은 하지 않는다.


int a = 10;
int b = 20; 
//컴파일 에러
a + b;

반면에 메소드란 참 어이 없게도 같은 결과값을 반환해도 별도의 변수로 받지 않아도 아무런 문제를 일으키지 않는다. 

즉 우리가 판단할 수 있는 사실은 객체의 메소드의 리턴타입이라는 것은 실제로 무언가 결과를 반환하는 것이 아니라 메소드의 특정 결과물을 메모리상에 변수처럼 공간을 만들어서 넣겠다는 뜻으로 해석해야 한다. 

다시 앞에서 나온 코드를 살펴보자. 

public class AccessTest {

private int result;
public int getResult(){
return result;
}
}

getResult( )메소드의 실행은 결과적으로 메모리 공간에 int에 해당하는 공간을 만들어 두고, 이 공간에 변수 result를 복사(Java에서는 복사라는 개념만이 존재하기 때문에)해 두는 방식을 사용하게 된다. 

잊지 말아야 할 것은

'메소드의 리턴타입이라는 것은 결국 메모리에 공간 할당하고 리턴 결과를 담아두는 것'






댓글 없음:

댓글 쓰기