[Java] Statement와 Expression
람다식을 공부하다가 식(expression)과 문(statement)에 대한 이해가 부족한 것 같아서 포스팅으로 정리합니다.
아래의 글을 많이 참조했습니다. 오류 정정 및 피드백 댓글로 주시면 감사하겠습니다.
www.oreilly.com/library/view/learning-java/1565927184/ch04s04.html
문장과 식 (Statement & Expressoin)
문장(Statement)은 프로그램 내에서 하나의 동작을 기술하는 것입니다. 자바에서 문장들은 블록( {} ) 안에 모여서 메서드와 클래스를 구성합니다. 문장의 끝에는 항상 세미콜론을 붙여줍니다.
public class MyClass {
[ sentence; ]
[ sentence; ]
[ sentence; ]
void myMethod() {
[ sentence; ]
[ sentence; ]
[ sentence; ]
}
}
변수 선언과 할당(Variable declaration and assignment), 조건문(Conditional statement), 반복문(Loop-statement) 등이 문장에 포함됩니다.
식(Expression)은 값을 기술하는 것입니다. 식은 반드시 컴파일러에 의해 값으로 평가될 수 있어야 합니다. 즉, 식은 하나의 값으로 치환됩니다. 함수 호출(method calls), 객체 할당(object allocations), 그리고 산술식 등이 모두 식에 포함됩니다.
그럼 식은 문장에 포함되는 걸까요? 문장이 프로그램의 동작을 기술하는 것이라면, 프로그램을 구성하는 코드 중에서 동작을 기술하지 않는 것이 있나요? 공부를 하면서 이 부분이 제일 헷갈렸는데요, 제가 이해한 바는 이렇습니다. 아래의 예시를 봅시다.
자바에서는 이런 문장이 가능합니다.
int i, j;
i = 5;
j = (i = 5);
i = 5; 하나만 놓고 보면, 의미적으로는 변수 i에 값을 할당하는 기능을 합니다. 자바에서 모든 문장의 끝에는 세미콜론이 붙어야 합니다. 두 번째 라인은 세미콜론이 붙지 않으면 컴파일 오류가 나죠.
하지만 세 번째 라인 j = ( i = 5 ); 에서는 i = 5 에 세미콜론이 붙지 않습니다. 이때 i = 5 는 j 에 할당되는 값으로 환원됩니다. 식으로 사용이 된거죠.
두 번째 라인의 i = 5 는 하나의 식으로 구성된 문장인 겁니다. 세 번째 라인의 i = 5 는 j 에 할당할 값을 산출할 식으로써 사용된 것이구요.
결론적으로 식을 문장에 포함되는 개념으로 보기는 어려울 것 같습니다. 대신 하나의 식으로 구성된 문장은 존재할 수 있죠. 이렇게 하나의 식으로 구성된 문장을 expression statement라고 합니다. 다음과 같은 것들이 expression statement입니다.
/Increment and decrement expressions
num++;
++num;
num--;
--num;
//Assignment expressions
num = 100;
num *= 10;
//Method invocation expressions
System.out.println("This is a statement");
someMethod(param1, param2);
조건문과 반복문을 봅시다.
if ( condition ) {
[ statement; ]
[ statement; ]
[ ... ]
}
while ( condition )
statement;
do
statement;
while ( condition );
자바의 조건문과 반복문에서 저 condition 안에는 오직 boolean expression만이 들어갈 수 있습니다. 예를 들어
int x = 5;
if (x > 3) {
//do something
}
위 코드에서 x > 3 은 비교 연산자를 통해 true 라는 진리값으로 환원(또는 계산)되기 때문에 식입니다. 이렇게 (함수 호출을 제외한) 모든 식은 값과 연산자로 구성됩니다.
그 외에 하나의 라인을 구성하지만 값으로 환원될 수 없는 것들, 예를들어 break, continue, return 등의 키워드는 모두 문장입니다.
식
문장에 대해서는 딱히 더 다룰게 없으니 식에 대해서 좀 더 알아보도록 합시다. Expression과 관련해 자료들을 읽다가 "식을 평가한다(evaluate expressions)"는 표현을 굉장히 자주 마주쳤습니다. 포스팅의 앞부분에 링크를 첨부한 오레일리 문서에서도 "식은 결과를 산출하기 위해 평가된다(An expression is evaluated to produce a result)"는 표현이 나오는데요. "계산한다" 정도로 번역하면 무리가 없을 듯 합니다.
앞서 말했듯이, 식은 값을 산출합니다. 식에는 함수 호출, 객체 할당, 산술식 등이 포함된다고 했죠. 산술식에서는 숫자 타입의 값을, 객체 할당에서는 참조 타입의 값을 산출합니다. 함수 호출에서는 앞의 두 타입을 포함해서 "void" 라는 조금 특별한 타입이 하나 더 존재합니다. void 타입의 메서드는 값을 반환하지 않지만 부수효과를 일으키는 것으로 평가됩니다.
null value
null도 값입니다. 따라서 어떤 문장이 null로 환원된다면 이 또한 식입니다. null은 모든 참조 타입에 대입될 수 있습니다. null은 "참조하고 있는 것이 없다(It has no reference)"는 것을 의미합니다.
변수 접근 (Variable Access)
닷(.) 연산자는 여러 기능이 있습니다. 이 연산자는 인스턴스 변수나 스태틱 변수로부터 값을 얻어내거나, 객체로부터 메서드를 호출하는데 사용됩니다. 닷 연산자를 사용한 문장은 접근된 변수의 값을 산출하는 식입니다.
int i;
String s;
i = myObject.length;
s = myObject.name;
int len = myObject.name.length( );
int initialLen = myObject.name.substring(5, 10).length( );
메서드 호출 ( Method Invocation)
메서드 호출 또한 식입니다. 이는 메서드에 선언된 타입의 값을 산출합니다. 앞서 말했듯이 void도 값으로 여겨집니다. 특정한 값을 반환하지는 않지만 해당 메서드가 일으키는 부수효과( 예를 들어 System.out.println("")은 콘솔창에 무언가를 출력하는 부수효과를 일으킴)로 평가됩니다.
객체 생성 (Object creation)
객체 생성은 new 연산자를 통해 이루어집니다. 이 또한 식입니다.
Object o = new Object( );
앞서 식을 통해 산출되는 값에 참조 타입이 있다고 말했는데, 값은 또 다른 식이나 문장에서 사용될 수 있다고 말했습니다. 객체의 생성은 참조 타입의 값을 산출하기 때문에 다른 식에 이용될 수 있습니다.
int hours = new Date().getHours( );
때문에 이렇게 new 연산자로 생성한 객체를 따로 변수에 할당하지 않고도 메서드를 호출할 수 있는 것입니다.
instanceof 연산자
instanceof 연산자를 사용하여 런타임에 객체의 타입을 확인할 수 있습니다. 이 식은 boolean 값을 반환합니다.
Boolean b;
String str = "foo";
b = ( str instanceof String ); // true
b = ( str instanceof Object ); // also true
b = ( str instanceof Date ); // false, not a Date or subclass
익명 클래스 (Anonymous Class)
익명 클래스도 하나의 식입니다. 만약 로컬 클래스를 정의하는 코드 블럭과 다를게 없다면 끝에 세미콜론이 붙을 이유가 없죠.
public class Hello {
interface Greeting {
void sayHello();
}
static class EnglishMan implements Greeting {
public void sayHello() {
System.out.println("Hi");
}
}
public static void main(String[] args) {
Greeting frenchMan = new Greeting() {
@Override
public void sayHello() {
System.out.println("Bonjuor");
}
}; //식으로 구성된 문장이기 때문에 끝에 세미콜론이 붙는다!
frenchMan.sayHello();
}
}