이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이선스에 따라 이용할 수 있습니다.
1. 자바 소개
1-1 자바 특징
자바는 고급 언어이며, 객체 지향 언어다.
소스 프로그램을 기계어로 변환하는 과정을 컴파일이라고 한다. 이 소프트웨어를 컴파일러라고 하며 각 언어 마다 고유한 전용 컴파일러가 있다.
자바 소스 파일 ->. java이고 컴파일 된 확장자 ->. class 이다.
자바와 자바스크립트는 다른 언어이다.
1-2 자바 역사
1991년 썬 마이크로시스템즈에서 오크(oak)라는 플랫폼 독립적이며 메모리 사용량이 적은 새로운 언어와 실행 체제를 개발하였다.
1995년 썬 마이크로시스템즈는 Sun World 95에서 마침내 자바라는 이름으로 발표한다.
2009년 Oracle에서 썬 마이크로시스템즈를 인수-> 현재 Oracle에서 자바를 제공.
1-3 자바의 플랫폼 독립성, WORA
자바는 플랫폼 종속성인 C/C++ 언어와는 달리 CPU와 운영체제에 영향을 받지 않고 자바 가상 기계(JVM)만 있으면 어떤 컴퓨터에서든 동일하게 실행되는 플랫폼 독립성을 가지고 있다.
1-4 자바 가상 기계와 바이트 코드
바이트 코드는 자바 컴파일러가 자바 소스 프로그램을 컴파일 한 일종의 기계어로서, JVM에 의해 실행되는 바이너리 코드이다.
바이트코드는 CPU에 의해 직접 실행되지 않고, 자바 가상 기계에 의해 인터프리터 방식으로 한 명령씩 해석되어 실행된다.
JVM은 플랫폼에 적합하게 서로 다르게 구현되므로 플랫폼 종속적이다. 하지만 이들은 모두 동일한 자바 프로그램에게 동일한 인터페이스와 실행 환경을 제공한다.
1-5 자바 응용프로그램 실행 환경
자바 컴파일 과정은 소스프로그램을 컴파일 하여 바이트 코드를 클래스 파일에 저장한다.
실행 되기 위해서는 개발자가 작성한 자바 프로그램 외에 자바 플랫폼에서 제공하는 다양한 클래스 라이브러리(JDK APIs)가 필요하다.
타 언어와의 차이점은 컴파일 과정에서 링크과정이 없다는 것이다.
2. 자바 개발 도구
Oracle은 용도에 따라 10여 가지의 서로 다른 자바 배포 판을 제공한다.
자바 배포 판은 JDK 라고도 불리며, JDK는 자바 컴파일러 등 자바 응용프로그램을 개발하는데 필요한 도구와 자바 응용프로그램이 실행 될 때 필요한 자바 가상 기계와 표준 클래스 파일들을 포함하는 JRE로 구성된다.
(JDK = JVM+JRE+Class file 등으로 구성)
2-1 Java SE (Standard Edition)
자바 표준 배포 판으로서, 데스크톱과 서버 응용프로그램 개발 플랫폼이다.
2-2 Java ME (Micro Edition)
모바일용 배포 판으로 휴대 전화나 PDA, 셋톱박스 같이 제한된 리소스를 갖는 하드웨어에서 응용프로그램 개발을 위한 플랫폼이다.
사진 1 java SE 구조(출처: http://download.oracle.com/javase/8/docs/)
2-3 Java EE (Enterprise Edition)
기업용 배포 판, 자바를 이용한 다중 사용자, 대규모 기업 응용프로그램 개발을 위한 플랫폼이다.
2-4 자바와 오픈 소스
오픈 소스 – 소프트웨어 제공자의 권리를 보존하며 소스 코드를 누구나 열람할 수 있도록 무상 공개한 소프트웨어 (java, Linux, Solaris 등이 있다.) 현재 Oracle은 대부분의 자바 소스를 GPL(GNU General Public License)로 오픈 하여 누구나 자바 소스를 열람하고 참조할 수 있게 함.
오픈 소스의 장점
- 오픈 소스를 참조함으로써 개발 시간 및 비용 단축
- 많은 인원의 참여로 오픈 소프트웨어를 개량함으로써 고품질 소프트웨어 개발 가능
오픈 소스의 단점
- 무단으로 상용화할 경우 저작권 침해가 발생할 수 있다.
- 다양한 개량 버전의 소프트웨어로 인한 호환성 문제가 생길 수 있다.
2-5 JDK와 JRE
JDK는 자바 개발환경 도구이며, 자바 컴파일러와 JRE, 클래스 라이브러리, 자바 응용프로그램 샘플 소스 등이 포함.
JRE는 자바 응용프로그램 실행 환경이며, 일반사용자는 JRE만 받아도 자바 프로그램을 실행 할 수 있다.
JDK의 설치 후 디렉터리 구조는 다음과 같다.
사진 2 JDK 설치 후 디렉터리구조 (출처: 명품 자바 에센셜, 황기태)
자바의 주요 개발 도구
- Javac – 자바 소스-> 바이트 코드 변환 컴파일러
- Java – 자바 프로그램 실행 기, JVM 작동시켜 자바 프로그램을 실행
- Javadoc – 자바 소스 프로그램으로부터 HTML 형식의 API 도큐먼트 생성
- Jar – 자바 클래스 파일을 압축한 자바 아카이브 파일(JAR) 생성, 관리
- Jdb – 자바 디버거
- Javap – 클래스 파일의 바이트코드를 소스와 함께 보여주는 디어셈블러
- Appletviewer – 브라우저 없이 자바 애플릿을 실행하는 유틸리티
2-6 자바 API
서로 관련된 클래스들을 분류하여 묶어놓은 것을 패키지라 부른다.
자바 API란 필요한 주요 기능들을 미리 작성하고 컴파일 하여 클래스 라이브러리로 묶어놓은 패키지들이다.
3. 자바 프로그래밍 기초
- 자바에서는 클래스 이름과 자바 소스 파일 이름이 일치해야 한다.
- 자바 소스파일의 확장자는. java이며, 파일명의 대소문자를 구분한다.
- 소스파일 작성 후 컴파일러(javac)는 컴파일 된 바이트 코드를. class 파일에 저장한다.
- 자바 프로그램의 실행은 Console 환경에서 확장자를 뺀 이름(ex Hello.java-> Hello로 실행)으로 java 명령을 이용하여 실행 할 수 있다.
3-1 시작함수 Main
public class Hello2030 {
public static void main(String[] args) {
System.out.println("메인코딩!!");
}
}
3-2 자바의 특징
- 플랫폼 독립성 – 자바는 독립적인 바이트 코드로 컴파일 된다. JVM만 있으면 실행 가능.
- 객체 지향 – 객체 지향 언어로서 캡슐화, 상속, 다형성 등을 지원한다.
- 클래스로 캡슐화 – 캡슐화 원칙을 지켜, 변수나 메소드는 반드시 클래스 내에 구현하도록 한다. 또한 내부 클래스(Inner Class)를 만들 수 있다.
- 소스와 클래스 파일 – 소스가 컴파일 된 클래스 파일에는 반드시 하나의 자바 클래스만이 들어 있다. 그러므로 하나의 자바 소스 파일에 여러 개의 클래스를 작성한 후 컴파일 하면 별도의 클래스 파일이 생성된다. (ex, 4개면 4개의 Class file)
- 실행 모듈 – 자바 응용프로그램은 한 개의 클래스 또는 다수의 클래스로 구성되고, jar 파일 형태로 압축 가능하다. 하나의 클래스 파일에 main() 메소드가 두 개 이상이 있을 수 없다. 각 클래스는 main()을 가지는 것이 가능하다.
- 패키지 – 서로 관련 있는 클래스는 패키지로 묶어 관리한다.
- 멀티스레드 – 하나의 자바 프로그램에서 다수의 스레드가 동시에 실행 할 수 있는 환경 지원. 운영체제의 지원 없이 자바는 멀티스레드 프로그래밍이 가능하다.
- 가비지 컬렉션 – 자바는 메모리를 할당 받는 기능은 있지만, 메모리를 반환하는 기능은 없다. 프로그램 내의 사용되지 않는 메모리는 JVM의 가비지 컬렉션 기능에 의해 자동으로 회수된다.
- 실시간 응용 시스템에 부적합 – 자바 응용프로그램은 실행 도중 예측할 수 없는 시점에 가비지 컬렉션이 실행되므로 프로그램 실행이 일시적으로 중단된다. 이런 문제로 인해 일정 시간(deadline) 내에 반드시 실행 결과를 내야만 하는 실시간 시스템에는 자바 언어가 적합하지 않다.
- 자바 프로그램은 안전하다 – 자바 언어는 타입 체크가 매우 엄격하며, C/C++와 달리 메모리의 물리적 주소를 사용하는 포인터의 개념이 없기 때문에, 잘못된 자바 프로그램으로 인해 컴퓨터 시스템이 중단 되는 일은 없다.
- 프로그램 작성이 쉽다 – 자바는 포인터 개념이 없어 작성이 편하다.
- 실행 속도 개선을 위해 JIT 컴파일러가 사용된다. - JVM 의 인터프리터 방식 개선을 위해 JIT 컴파일러로 프로그램 실행 도중 해당 CPU에 기계어 코드를 컴파일하고 CPU가 바로 기계어를 실행하도록 한다.
3-3 자바 프로그램 기본 구조
public class Hello {
public static int sum(int n, int m) {
return n+m;
}
public static void main(String[] args) { //Public == 접근 지정자
int i = 20;
int s;
char a;
s = sum(i,10);
a = '?';
System.out.println(a);
System.out.println("hello");
System.out.println(s);
}
}
3-4 클래스 선언
자바에서는 클래스 밖에 변수, 상수, 메소드, 전역변수 등을 생성 할 수 없다.
3-5 식별자
식별자란 클래스, 변수, 상수, 메소드에 붙이는 이름을 말한다.
식별자 이름 규칙
- 특수문자, 공백은 식별자로 사용할 수 없으나 _, $는 예외다.
- 식별자로 한글을 사용할 수 있다.
- If, while, class 등 자바 언어의 키워드는 식별자로 사용할 수 없다.
- 식별자의 첫 번째 문자로는 숫자는 사용할 수 없다.
- Ture, false, null은 식별자로 사용할 수 없다.
- 대소문자를 구별한다.
- 길이 제한이 없다.
3-6 데이터 타입
기본타입 8개 – Boolean, char, byte, short, int, long, float, double
레퍼런스 타입 1개 – 배열에 대한 레퍼런스, 클래스에 대한 레퍼런스, 인터페이스에 대한 레퍼런스
사진 3 자바의 기본 타입
주의해야 할 타입은 char이다. C/C++에서의 char는 1byte 이지만, 자바는 유니코드를 나타내기 위해서 2byte를 사용한다.
3-7 문자열
자바에서의 문자열은 기본 데이터 타입이 아닌 String 클래스를 이용한다. 또한 + 연산자를 이용하여 문자열끼리 연결이 가능하다.
public class String1 {
public static void main(java.lang.String[] args) {
String toolName="jdk";
System.out.println( toolName + "1.8");
}
}
4. 변수, 연산자, 수식
4-1 변수와 선언
public class String1 {
public static void main(java.lang.String[] args) {
int radius;
double weight=75.57;
char c1,c2,c3='a';
System.out.println(c1); //초기화 안됨
System.out.println(c2); //초기화 안됨
System.out.println(c3); //'a'로 초기화
}
}
변수를 나열하여 선언 할 때는 = 연산자로 초기화를 하지 않으면 초기화되지 않고 선언만 된다.
4-2 리터럴(Literal)
정수 리터럴은 10진수, 8진수, 16진수, 2진수로 표현 가능하며, 자바에서는 int 타입으로 컴파일 된다. Long 타입으로 지정할 시 L이나 l을 붙여주면 가능하다.
사진 4 정수 리터럴
실수 리터럴은 소수점 형태나 지수 형태로 실수를 표현한 값이다. 실수 리터럴은 double 타입으로 자동 처리된다.
double d = 0.1234;
double e = 1234E-4;
float f = 0.1234f;
double w = .1234D;
문자 리터럴은 ''로 문자를 표현하고나 \u 다음에 문자의 유니코드 값을 사용하여 표현한다.
char a = 'w';
char b = '글';
char c = \uae00;
특수문자 리터럴은 Escape Sequence라고도 한다.
사진 5 특수문자 리터럴
논리 타입 리터럴은 ture, false 두 개이고, Boolean 타입의 변수에 직접 치환하거나 조건문에 사용한다.
4-3 상수
리터럴을 상수로 선언하면 변수처럼 표현이 가능하다. 상수는 final 키워드를 사용하여 선언한다. 상수 선언 시에는 Static 키워드를 이용하는 것이 바람직하다.
public class String1 {
public static void main(java.lang.String[] args) {
final double PI =3.14;
double radius = 10.2;
double circleArea=radius*radius*PI;
System.out.println("반지름"+radius+",");
System.out.println("원의 면적 = " + circleArea);
}
}
4-4 타입변환
자동 타입 변환 – 치환 문이나 수식 내에서 타입이 일치하지 않을 때, 컴파일러는 작은 타입 -> 큰 타입으로 자동 변환한다.
강제 타입 변환 – 캐스팅(casting) 이라고 부르며, 큰 타입을 작은 타입에 강제적으로 변환 시킬 때 사용한다.
public class String1 {
public static void main(java.lang.String[] args) {
//자동 타입 변환
int m = 25;
double d = 3.14*10;
//강제 타입 변환
double g = 1.9;
int n = (int)g;
}
}
4-5 표준입력
System.in는 자바에서 제공하는 것으로 표준 입력 스트림 객체이다. System.in을 직접 사용하는 응용프로그램은, 받은 바이트 정보를 문자나 숫자로 스스로 변환해야 하는 번거로움이 있어 Scanner클래스를 이용한다.
사진 6 스트림 클래스의 주요 메소드
import java.util.Scanner;
public class input {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String name = scanner.next();
System.out.println("당신의 이름은 "+name+"입니다." );
scanner.close();
}
}
4-6 연산자
사진 7 자바의 연산자 종류
시프트는 >>, << 각각 나누기 2, 곱하기 2와 같다.
최상위 비트의 빈자리를 시프트 전의 최상위 비트로 다시 채우는 산술 시프트 >>(2개)
최상위 비트를 무조건 0으로 채우는 논리 시프트가 있다. >>>(3개)
조건 연산자는 세 개의 피 연산자로 구성되어 삼항 연산자라고도 하며 형식은 다음과 같다.
조건 ? call1 : call2
위의 식에서 조건이 참이면 call1이 실행되고 거짓이면 call2가 실행된다.
5. 조건과 반복
5-1 조건문
단순 if문
public class input {
public static void main(String[] args) {
int n = 4;
int score = 85;
if (n % 2 == 0) {
System.out.print(n);
System.out.println("는 짝수입니다.");
}
if (score >= 80 && score <= 89)
System.out.println("학점은 B입니다.");
}
}
if-else 문
public class input {
public static void main(String[] args) {
int n=4;
if(n%2==0){
System.out.print(n);
System.out.println("는 짝수입니다.");
}
else{
System.out.print(n);
System.out.println("는 홀수입니다.")
}
}
다중 if-else문
public class input {
public static void main(String[] args) {
int score = 70;
char grade;
if (score >= 90)
grade = 'a';
else if (score >= 80)
grade = 'b';
else if (score >= 70)
grade = 'c';
else
grade = 'd';
}
}
중첩 if-else문
public class input {
public static void main(String[] args) {
int score = 60;
int year = 5;
if (score >= 60) {
if (year != 4)
System.out.println("합격!");
else if (score >= 70)
System.out.println("합격!");
else
System.out.println("불합격!");
}
}
}
Switch 문
public class input {
public static void main(String[] args) {
char garde = 'B';
switch (grade) {
case 'A':
System.out.println("축하합니다");
System.out.println("축하합니다");
break;
case 'B':
System.out.println("좋아요. ");
break;
case 'C':
System.out.println("노력하세요. ");
break;
default:
System.out.println("탈락입니다!");
}
}
}
case문에 지정하는 값은 정수 리터럴, 문자 리터럴, 문자열 리터럴만 허용한다. 또한 변수나 식을 사용할 수 없다.
5-2 반복문
For문
public class input {
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
System.out.print(i);
}
}
반복 후 작업 문에는 콤마(,)로 분리하여 여러 문장을 둘 수 있다.
public class input {
public static void main(String[] args) {
for (int i = 0; i < 10; i++, System.out.println(i)) {
}
}
}
for 문으로 무한 반복을 하고자 하면 다음과 같은 문장을 쓸 수 있다.
public class input {
public static void main(String[] args) {
for (int i = 0; ; i++, System.out.println(i)) {
}
}
}
public class input {
public static void main(String[] args) {
for (int i = 0; true; i++, System.out.println(i)) {
}
}
}
while문
public class input {
public static void main(String[] args) {
int i = 0;
while (i < 10) {
System.out.print(i);
i++;
}
}
}
do-while문
public class input {
public static void main(String[] args) {
char a = 'a';
do {
System.out.print(a);
a = (char) (a + 1);
} while (a <= 'z');
}
}
중첩 반복문
public class input {
public static void main(String[] args) {
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
System.out.print(i + "*" + j + "=" + i * j);
System.out.print('\t');
}
System.out.println();
}
}
}
continue문은 for문에서는 반복 후 작업으로 분기하고, while문에서는 조건식으로 다음과 같이 분기한다.
import java.util.Scanner;
public class input {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("정수 5개를 입력하세요.");
int sum = 0;
for (int i = 0; i < 5; i++) {
int n = scanner.nextInt();
if (n <= 0)
continue;
else
sum += n;
}
System.out.println("양수의 합은 " + sum);
}
}
break문은 하나의 반복문을 즉시 벗어날 때 사용하며 아래와 같이 그 차체가 하나의 문장이다.
import java.util.Scanner;
public class input {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("exit를 입력하면 종료합니다.");
while (true) {
System.out.println(">>");
String text = scanner.nextLine();
if (text.equals("exit"))
break;
}
System.out.println("종료합니다");
scanner.close();
}
}