$ java
이렇게 java 명령을 실행하면 어떤 프로그램을 실행하라는 지시를 하지 않았기 때문에, 자바를 실행하는 데 필요한 각종 옵션들이 출력된다.
$ javac
javac를 실행할 때에도 뒤에 아무런 옵션을 주지 않았기 때문에 각종 옵션들에 대한 설명이 나열된다.
$ java -version
이 명령어를 통해 어떤 JDK가 설치되어 있는지 확인 가능하다.
컴파일은 javac 명령을 사용하고 실행은 java 명령을 사용한다.
대부분의 프로그래밍 언어들은 텍스트로 된 파일로 실행할 수가 없다. 텍스트 파일들을 컴파일(compile : 엮다)이라는 단계를 거쳐야지만 프로그래밍 언어를 실행하는 프로그램이 실행을 할 수 있다. 내가 만든 프로그램 코드를 컴퓨터가 이해할 수 있도록 번역해주는 작업이 바로 컴파일이다. (엮어주다는 뜻보다는 번역하다는 뜻이 더 어울려 보인다)
.java라는 확장자로 되어 있는 소스를 컴파일하면 .class라는 확장자를 가진 파일이 생성되어 디스크에 저장된다. 이 .class 파일은 바이트 코드로 되어 있다. 바이트 코드는 자바 가상 머신(Java Virtual Machine, JVM)이 실행할 수 있는 중간 형태의 코드이다.
컴파일을 하는 프로그램을 컴파일러라고 부르며, 윈도우에서는 javac.exe라는 프로그램, 맥이나 리눅스에서는 javac가 그 역할을 수행한다. 컴파일을 할 때 개발자가 만든 프로그램이 규칙을 지키지 않았다면, 컴파일러는 오류를 내뿜으면서 컴파일이 되지 않는다.
컴파일을 마친 .class 파일은 JVM에서 읽어서 운영체제에서 실행된다.
참고
[기본기] 깊게 고민 못하는 초보 개발자가 이해해보는 개발 기본기 시리즈 (2): 컴파일을 그림 3장으로 정리해보기
자바 컴파일 과정: 소스코드부터 실행까지
[Java] 컴파일 과정
바이너리는 우리나라 말로 0과 1로 구성되어 있는 2진법을 의미한다. 그래서 바이너리 파일은 2진수로 채워져 있는 파일을 말한다. (0과 1로만 채워져있는 파일)
사람은 글자로 읽는 것이 더 편하고 빠르겠지만, 컴퓨터는 2진 파일을 읽는 것이 훨씬 빠르기 때문에 컴퓨터가 읽기 위한 파일들은 대부분 바이너리로 되어 있다.
콘솔창에서 $ javac HelloGodOfJava.java처럼 javac라는 명령어를 사용하면 텍스트로 만든 자바 파일을 컴파일러가 읽어서 오류가 없나 확인해 본다. 그리고 모든 것이 정상이라면 컴파일러가 .class 파일을 만든다.
java라는 실행 프로그램은 .class라는 확장자를 지정해주면 안 되고, 개발자가 소스 파일을 만들 때 지정한 이름만 적어주면 된다. 그러면 알아서 .class 파일들을 찾아서, 동일한 이름의 클래스를 찾아 실행한다.
"실행을 목적으로 하는" 모든 자바 클래스는 main() 메소드가 반드시 있어야 한다. main() 메소드가 없는 클래스는 실행을 목적으로 하는 클래스가 아니기 때문에 없는 것이다.
하지만, java 명령으로 실행하는 자바 프로그램의 진입점(시작점)은 main() 메소드이기 때문에 반드시 있어야 한다. 자바 기반으로 실행되는 모든 프로그램에 있는 수많은 클래스 중에 main() 메소드가 있는 클래스가 적어도 하나 존재하고, 프로그램이 실행될 때 그 메소드가 수행되는 것이다.
public static void main(String[] args) {
}
System.out.println("Hello God of Java !!!!!");
이 줄을 가만히 살펴보면 println() 이라는 메소드를 호출한 것이다. 그리고 System.out은 System 클래스에 있는 static한 out이라는 필드를 의미한다. 그리고 매개 변수로 "Hello God of Java !!!!!"라는 문자열을 넘겨 주었다.
줄을 바꿔서 출력할 일이 있으면 println(), 줄을 바꾸지 않고 연달아서 출력하려면 print() 메소드를 사용하면 된다.
주석 처리된 글자는 컴파일할 때 무시된다.
//
한줄만 주석 처리를 한다. 여기서 한 줄은 세미콜론(;) 기준의 한줄이 아닌 말 그대로 코드 상의 한줄을 의미한다.
가장 많이 쓰이는 경우는 디버그용으로 코드를 잠시 감추려고 할 때 사용하고, 개발자가 소스에 대한 간단한 설명을 적어 놓을 때 사용되기도 한다.
/*
*/
여러 줄을 한꺼번에 주석 처리할 때 사용된다. 이 블록 주석은 반드시 시작(/*)과 끝(*/)이 있어야만 한다. 메소드 안의 여러 줄을 주석 처리하거나, 메소드 자체를 주석 처리할 때 보통 사용한다.
/**
*/
public class HelloGodOfJava {
/**
*/
public void sampleMethond() {
}
}
클래스 선언 앞이나, 메소드 선언 바로 앞에 있으면 문서용 주석으로 인식되어 처리된다. 보통 API 문서에서 자주 보이는 주석이다.
void main() {
}
이 중 반드시 있어야 하는 것은 2. 리턴 타입, 3. 메소드 이름, 6. 메소드 내용이다.
public class Profile {
public static void main(String[] args) {
String name = "홍성덕";
int age = 29;
System.out.println("My name is " + name);
System.out.println("My age is " + age);
}
}
/* 로 시작하고, */로 끝나는 사이에 있는 소스들을 어떻게 되나요?나의 답변
1. public static void
2. String[] 타입의 매개변수가 들어가며 문자열로 구성된 배열 타입을 의미한다.
3. 아니오
4. 문자열을 출력하는 용도로 사용한다.
5. print() 메소드는 줄바꿈이 되지 않는 메소드이고, println()은 줄바꿈이 되는 메소드이다.
6. 한줄 주석으로 컴파일러가 주석 뒤에 오는 코드를 무시한다.
7. 주석 처리되어 컴파일러가 소스를 무시한다.
8. 리턴 타입, 메소드 이름, 메소드 내용
정답
1. public static void
다시 말해서
public : 어떤 클래스에서도 접근 가능하며
static : static 메소드이며 (객체를 생성하지 않아도 접근 가능한 메소드이며 "C.1"장에서 자세히 살펴본다.)
void : 리턴 값이 없음
을 의미한다.
2. String[] args. 즉, String문자열의 배열이 들어간다. 이 배열에 대한 설명은 "B.4"장에서 자세히 살펴본다.
3. public static void main(String args[]) 로 선언되어 있는 메소드가 클래스에 없으면, 해당 클래스를 실행할 수는 없다.
4. System.out.println() 메소드는 자바를 실행한 창에서 문자열을 출력하는데 사용된다.
5. System.out.print() 메소드는 줄바꿈을 하지 않기 때문에, 이 메소드 호출 후에 출력 메소드를 호출하면 같은 줄에 결과가 출력된다. 하지만, System.out.println() 메소드는 내용을 출력한 다음에 줄바꿈을 한다.
6. //는 한 줄 주석을 의미한다. 따라서, 해당 코드의 // 뒤에 있는 모든 내용은 무시된다.
7. /*으로 시작하여 */으로 끝나는 주석은 블록 주석으로, 해당 블록 내의 모든 내용은 무시된다.
8. 메소드에는 반드시 "리턴 타입", "메소드 이름", "메소드 내용"이 있어야만 한다.