Java 공부 (1)
Sparta Java handbook 학습으로, Java에 대한 기본 공부를 위한 필기입니다.
01. 언어의 역사
우리 사람은 1+3 이라고 하면 바로 이해하고 계산할 수 있지만 컴퓨터는 이를 0과 1로 표현해야 합니다. 컴퓨터가 이해할 수 있게 ‘01010101 00000001 00001001’ 이렇게 표현이 되는 언어를 우리는 기계어 라고 부릅니다.
기계어는 사람의 입장에서는 어렵기에 기계 명령어와 일상 용어를 일대일로 매칭하는 기계어와 니모닉의 매칭 코드표를 만들었습니다.
02. 어셈블리어
매칭 코드표를 어셈블리라고 합니다. CPU마다 실행할 수 있는 기계어가 달랐기에 어셈블리어도 다르게 만들어졌습니다. 어셈블리어를 기계어로 변역해주는 SW는 어셈블러라고 부릅니다.
애드삭 어셈블리어 개발자가 유니박 어셈블리어 프로그래머로 이직 하려면 유니박용 어셈블리어를 다시 배워야 했고, 이를 위해 어셈블리어 이후 많은 언어들이 등장했습니다.
03. C언어
어셈블리어로 개발 할 때는 같은 작업을 수행하는 소스 파일을 각 기계의 종류만큼 만들어야 했지만 C언어는 소스 파일을 하나만 만들어도 됩니다.
C언어는 하나의 소스 파일을 각 기계어에 맞는( ex. Windows용 C 컴파일러, Mac용 C 컴파일러 등) 컴파일러로 *컴파일을 하여 기계어 목적 파일을 만들기에 개발자는 소스 파일이 동작하는 기계에 상관없이 개발이 가능해졌습니다. -> 하나의 소스 파일만 작성하면 모든 기종의 컴퓨터에서 실행 가능
*컴파일 : 컴퓨터는 0과 1만 이해할 수 있습니다. 자연어를 컴퓨터에 입력해도 이것을 0과 1로 이루어진 이진코드로 해석해야 합니다. 컴파일이란 사람이 이해하는 언어를 컴퓨터가 이해할 수 있는 언어로 바꿔주는 과정입니다. 또한 이와 같은 컴파일의 기능을 수행하는 것을 컴파일러라고 부릅니다.
- 하지만 어떤 OS인지에 따라 int 타입을 2바이트, 혹은 4바이트로 인지할 수 있습니다.
04. JAVA
JAVA는 객체지향 언어입니다.
객체지향 언어는 클래스(Class) 가 있습니다. C++은 클래스 없이도 개발이 가능하기에 객체지향지원 언어라고 부르기도 합니다.
JAVA는 클래스 없이 개발이 불가능합니다. main() 메서드로 볼 때 C++은 클래스와 별개로 존재할 수 있지만 Java는 무조건 클래스 내부에 존재해야 합니다.
Java는 단 하나의 소스 파일로 모든 기종의 컴퓨터에서 실행 가능합니다.
Java는 크게 LTS 버전과 non-LTS 버전으로 나뉩니다. LTS는 후속 버전이 출시되어도 일정 기간 동안 지원을 지속하고 non-LTS 버전은 지원이 종료됩니다.
JDK(Java Development Kit) :자바 개발 도구
– Java App 개발을 위해 반드시 필요하며 사람이 작성한 소스 코드를 번역하여 컴퓨터가 이해할 수 있는 바이트 코드로 변환하는 도구인 Java 컴파일러가 포함되어 있습니다.
– 일반적으로 OpenJDK + 제조사의 부가 기능으로 구성되며 대표적인 것은 Oracle JDK 입니다. JDK에는 JRE가 포함되어 있으므로 별도로 분리하여 설치할 필요가 없습니다.
Oracle JDK는 유료 구독 모델을 적용하였습니다. Java라는 언어 자체는 오픈 소스이며 사용에 제약이 없지만 Oracle JDK의 특정 버전에 대한 지원을 받기 위해 Oracle과 구독 계약을 맺어야 하는 것이 변경된 정책입니다.
JRE(Java Runtime Environment) : 자바 실행 환경, JVM(Java Virtual Machine) : 자바 가상 기계
– Java로 컴파일 된 App을 실행하는 역할을 합니다. 모든 Java App은 JVM이라는 가상의 컴퓨터 공간에서 실행되고 Windows, Linux, Mac 등 어떠한 OS라도 JVM이 설치되어 있다면 Java App을 실행할 수 있습니다.
05. Java와 C언어의 차이점
- Java는 소스 파일을 하나만 작성하면 어디에서든지 사용 가능하고 C언어는 하나의 소스파일로 각 기계에 맞는 목적파일로 만들어 어디든 사용 가능합니다.
하나의 목적파일로 어디든 실행이 가능한가, 다수의 목적 파일을 만들어서 각 기계에 맞게 사용하냐의 차이점
Java는 반기계어인 바이트코드(.class)로 이는 OS가 아니라 JVM에서 사용됩니다.
소스 코드를 바이트 코드로 컴파일 해주는 것이 자바 컴파일러(javac)입니다.
main 함수 작성
– Java로 작성된 프로그램을 실행할 때는 main 함수로 진입하고 작성된 소스의 작업을 모두 수행하면 main 함수가 종료됩니다.
–
System.out.println(출력값);
은 콘솔에 값을 출력하기 위한 Java 함수입니다.IntelliJ에서는
sout
라는 글자를 입력하면System.out.println();
을 자동으로 작성해줍니다.
06. JAVA 실행과정
- 개발자는 자바 소스 파일(.java)를 작성합니다.
- JDK가 제공하는 javac를 사용하여 소스 파일을 컴파일 합니다.
- JVM의 Class Loader는 컴파일로 생성된 바이트 코드(.class)를 전달 받아 동적 로딩을 통해 실행에 필요한 클래스들을 로딩하여 JVM 내부 Runtime Data Area에 로드합니다.
JVM의 Execution에 의해 기계어로 해석되어 실행됩니다.
Compile 언어
– 소스 파일 전체를 컴파일 한 후 기계어를 CPU와 메모리를 통해 읽어서 바로 실행하는 방식으로 동작이 되는 언어로 C, C++, Java, C# 등의 언어가 있습니다.
– 소스 파일의 크기가 크면 컴파일 과정이 오래 걸릴 수 있습니다.
– 컴파일 된 후 기계어로 바로 실행이 되므로 실행 속도가 빠릅니다.
– Java는 javac에 의해 바이트코드로 컴파일 되지만 JVM에서는 인터프리터로 실행되므로 Compile언어이지만 Interpreter 언어의 특징을 동시에 가집니다.
Interpeter 언어
– 소스 파일을 컴파일 하지 않고 Interpreter를 사용하여 소스 파일을 한줄씩 번역하면서 실행하는 방식으로 동작이 되는 언어로 Javascript, Ruby, Python 등의 언어가 있습니다.
– 컴파일 언어처럼 별도의 목적파일이 존재하지 않습니다.
– Interpreter만 존재하면 어디든지 실행이 가능하므로 자유롭고 독립적입니다. 그리고 실시간으로 번역되기에 실행 속도가 느립니다.
07. 변수
- 단 하나의 값을 저장할 수 있는 메모리 공간을 의미합니다.
변수 공간에 기록된 값은 고정되어있지 않으며 다른 값이 기록되면 덮어 씌워질 수 있습니다.
- 메모리 공간은 1Byte 로 구성되어 있습니다.
메모리 공간은 메모리 주소를 가지고 있습니다.
- 메모리에 값을 저장하거나 읽을 때 해당 메모리 주소를 사용해야 하는데 사람이 사용하기에는 불편하므로 특정 메모리 영역에 이름을 붙이고 주소 대신에 이름을 사용해서 메모리에 값을 저장하고 읽을 수 있게 한 것이 변수입니다.
byte 1bytes = 8bits, short 2bytes = 16bits, int 4bytes = 32bits, long 8bytes = 64bits
- 변수 생성 규칙
대소문자 구분, 예약어 사용 불가, 숫자로 시작 불가
- 변수 초기화
변수에 처음으로 값을 저장하는 것을 의미
08. 상수
한 번만 값이 저장 가능한 변수입니다.
선언 방법 :
final 변수타입 변수이름;
숫자에 의미있는 이름을 붙여 코드 자체의 가독성을 늘리기 위해 상수를 사용합니다. ex) 시험의 만점은 100점이다.
09. 리터럴
그 자체로 값을 의미하는 것입니다.
기존의 상수와 같은 의미이지만 Java에서 상수를 한번만 값이 저장 가능한 변수라는 의미로 사용하기 때문에 이를 구별하기 위해 사용하는 용어입니다.
정수형의 int, 실수형의 double은 기본형이기에 접미사를 붙이지 않고, long 타입은 구분을 위해 50L처럼 리터럴 마지막에 접미사로 L을 붙입니다.
byte, short 타입 변수도 리터럴 접미사가 없습니다.
실수형의 float의 리터럴에는 f, double의 리터럴에는 d가 붙습니다. 실수형은 2개밖에 존재하지 않기에 접미사 f를 사용해 구분할 수 있게 되어 접미사 d는 생략 가능합니다.
boolean은 true, false만 가능, (boolean default value : false)
char grade = 'A'
이와 같이 하나의 문자만 가능 char -> ‘A’ String -> “A” String은 한 문자, 여러 문자 가능byte val = 127
범위가 지정되어 있음 128이면 errorshort sval = 128
1 2 3 4 int ob = 0b0101 //2진수 int i = 100 //10진수 int oct = 0100 //8진수 int hex = 0x100 //16진수long은 _를 사용하여 숫자 표현 가능
long count = 2_147_123_123L
, int 범위를 넘지 않는다면 L 생략 가능
1 2 3 4 5 float f1 = 10f; // 10.0f double d1 = 10.; // 10.0 double d2 = .10; // 0.10 double d3 = 1e3; // 1000.0 , e3 = 10의 3제곱 double d4 = -1e3; // -1000.0
10. 구별
1
2
3
4
5
6
public class Hello {
public static void main(String[] args) {
int score = 50;
final int finalScore = 100;
}
}
score
: 변수finalScore
: 상수50, 100
: 리터럴
11. 기본형
논리형 : boolean 문자형 : char 정수형 : byte, short, int, long 실수형 : float, double
- 1bit : 0, 1
- n비트로 표현할 수 있는 값의 개수 : 2^n개 입니다
8bit = 2^8 : 256개
- n비트로 표현할 수 있는 부호 없는 정수의 범위 : 0 ~ 2^n-1
8bit : 0 ~ 255
- n비트롤 표현할 수 있는 부호 있는 정수의 범위 : -2^(n-1) ~ 2^(n-1) -1
8bit : -128 ~ 127
- 정밀도 : ‘소수점 몇 자리까지 오차 없이 표현할 수 있는가’를 뜻합니다.
- S는 부호로 양수인지 음수인지를 표현합니다.
- E는 지수로 2의 지수를 표현합니다.
M은 가수로 소수점 이하를 표현합니다.
- float의 가수는 23자리인데 정규화를 통해 24자리까지 표현 가능합니다. 2^24 까지 표현이 가능한데 2^24는 10^7 < 2^24 < 10^8 이므로 정밀도는 7자리입니다.
실수형은 +-M x 2^E 형태로 저장되기에 int와 같은 4byte 크기의 float이 int보다 더 큰 범위의 값이 저장 가능합니다.
아스키코드 – 128개의 문자 조합을 제공하는 7비트 부호입니다.
유니코드 – 나라별 언어를 모두 표현하기 위해 나온 코드 체계입니다. – 문자마다 고유한 코드 값을 제공합니다. – 16비트로 표현합니다.
UTF-8 – 유니코드를 사용하는 인코딩 방식 중 하나입니다. – 영문/숫자/기호는 1byte로, 한글/한자는 3byte로 표현합니다. – 전 세계 모든 글자들을 한번에 표현 가능합니다.
정수형 오버플로우 – 정수형은 해당 변수 타입의 최솟값, 최댓값 범위를 넘어가면 값을 순회합니다.
예시)
1 2 3 4 5 6 7 8 9
short sMin = -32768; short sMax = 32767; // short 타입에서 최솟값 범위를 넘었을 때 // sMin - 1 = 32767 System.out.println("sMin = " + sMin); //sMin = -32768 System.out.print("sMin - 1 = "); //sMin - 1 = 32767 System.out.println((short)(sMin - 1)); //sMax = 32767
- 문자와 숫자 변환 – 숫자 + ‘0’ : 문자 – 문자 - ‘0’ : 숫자 – 숫자 + “” : 문자열 – 문자 + “” : 문자열
12. 참조형
기본형을 제외한 나머지 타입을 뜻합니다.
참조형 변수는 null 또는 메모리 주소를 저장합니다.
타입에 관계 없이 변수의 크기가 항상 4byte입니다.