Chapter 01 / 자바 시작하기
해당 챕터는 책이 아닌 항해에서 제공하는 노션페이지를 따라 진행하며
사전 스터디 당시에 환경설정을 해서 정리해놓은 글이 있으므로 링크로 대체
설치)
java 11(LTS) 로 설치
JDK] JDK 종류 3 : Azul zulu 설치
0. Azul zulu 란? Azul zulu (아줄 줄루)는 Open JDK를 기반으로 빌드된 JDK이다. * JDK : Java Developer Kit. 자바를 이용한 개발을 할때 필요한 여러 도구들을 모아서 제공하는 개발자용 자바 * Oracle에서 받는 JDK
littlezero48.tistory.com
본학습과정에서는 Community 버전 말고 Ultimate 로 진행
IDE] java IDE 종류 2 : intelliJ IDEA 설치
0. intelliJ IDEA(인텔리제이 아이디어) 란? 줄여서 intelliJ(인텔리제이) 혹은 IDEA (아이디어) 인털리제이 아이디어는 2001년에 처음 출시되었으며, 고급 코드 탐색 및 코드 리팩터링 기능 등의 특징을
littlezero48.tistory.com
JDK vs JRE vs JVM
많이들 헷갈려하는 부분으로 정리 해놓고 가자
JDK (Java Development Kit) |
어플리케이션 개발을 위해 필요한 것을 묶어 놓은 것을 말한다. 사람이 작성한 소스코드를 컴퓨터가 이해할 수 있는 바이트 코드로 변환하는 도구인 컴파일러는 물론 JRE도 포함하고 있다. 일반적으로 무료로 공개된 OpenJDK를 기준으로 제조사의 부가기능 더한 형태로 구성되어 있다. |
JRE (Java Runtime Environment) |
Java로 컴파일 된 어플리케이션을 실행, JVM을 구현한다. Java 파일을 실행하기 위한 환경이며, JVM이 실행에 필요한 라이브러리를 포함하고 있다. |
JVM (Java Vitual Machine) |
자바 바이트 코드(*.class)를 해당 컴퓨터의 명령어로 해석해주는 역할을 하는 인터프리터 이다. JVM이 플랫폼(OS)에 의존적인것과 다르게 플랫폼 제약이 없으며 한줄한줄 읽어 실행하는 컴파일러와 다르게 모든 명령을 한번에 읽고 실행하기 때문에 컴파일러 보다 느리다. |
참조 :
[Java]JVM, JRE, JDK 의 차이 - 자바의 흐름, JVM 구조
자바에서 사용하는 개념 중에 많이 혼동하는 용어를 정리합니다. 일부 티스로리 블로그에서 잘못된 표현(J...
blog.naver.com
프로젝트 생성하기)
Empty Project를 생성 처음엔 Out 폴더가 생성되지 않음. 한번 빌드하면 Out폴더가 같이 생성
* java프로그램의 실행단계
java로 작성된 프로그램은 main함수로 진입한다. main 로 진입하여 그 안에서 작성된 소스의 작업을 모두 수행하면 main 함수 종료 이는 곧 프로그램의 종료
* Java는 하나의 명령 단위가 끝났다는 의미를 전달하는 표시로 세미콜론( ; )을 사용하여 소스를 종결
+ 명령라인으로 컴파일하고 실행하기
책의 Oracle JDK랑은 달리 Azul Zulu JDK라서 그런 걸까? 이클립스와 인텔리제이의 차이인걸까?
별도의 옵션 필요없이 컴파일과 실행이 간단하게 된다.
왜 차이가 나는 건지 좀 더 찾아볼 필요가 있다.
+ 은솔님이 가르쳐주셨던 모듈이라는 개념에 대한 두 IDE에서의 차이점 비교글: (https://whitepaek.tistory.com/47)
Chapter 02 / 변수와 타입
02-1 / 변수
변수의 정의)
변수는 값을 저장할 수 있는 메모리의 특정 번지에 붙이는 즉, 메모리 공간의 이름.
변수를 통해 메모리의 특정 번지 값을 저장하고 읽으면서 사용한다. 메모리에 값을 저장하고 싶다면 변수를 선언 변수에 값을 지정한다. 어디에 지정할지 어떤 방식으로 저장할지는 프로그래밍 언어와 운영체제가 정하는데 자바의 경우 JVM이 이 일을 한다.
자바의 경우 선언할때 결정해주는 타입의 값만 해당 변수에 저장할 수 있고 변수 하나에 하나의 값만 저장할 수 있다.
변수 선언)
변수를 선언할 때 변수에 어떤 타입의 데이터를 저장할 지 그리고 변수 이름을 무엇을로 할지 결정
int x;
char y;
double z;
// 같은 타입의 변수는 콤마로 선언할 수 있다
int a, b, c;
// 변수랑 값을 같이 선언할 수도 있다 / 변수 초기화
int a = 5;
변수 이름은 자바가 명명한 이름 규칙을 따라야 한다.
- 첫번째 글자는 문자, $, _ 이어야하고 숫자로 시작할 수 없다
- 영어 대소문자 구분
- 자바에서 변수 명명 관례로는 캐멀케이스를 사용
- 길이 제한은 없음
- 자바 예약어를 사용할 수 없다
* 예약어 : 프로그래밍 언어에서 의미를 이미 갖고 사용되는 단어
값 저장)
변수에 값을 저장할 때에는 대입 연산자 (=)를 사용한다.
int i = 90;
// i는 90이다 라는 의미가 아니라 i에 90을 대입한다. 넣는다. 라는 의미
변수 이름만 선언해주면 변수를 생성되지 않는다! 변수에 값이 저장될 때 변수가 생성되는데 이를 변수 초기화라 한다.
그리고 이때 사용되어진 값이 초기값이다.
int value;
int result = value + 10;
// 컴파일 에러
따라서 위와 같이 값이 저장되지 않는 변수를 사용한 코드는 에러가 발생한다. 제대로 사용하려면 아래처럼 초기화해준다.
int value = 30;
int result = value + 10;
// 40
변수 사용)
변수는 출력문이나 연산식 내부에서 변수에 저장된 값을 출력 및 연산할 때 사용
아래처럼 같은 변수라도 출력문에 사용하느냐 연산식에 사용하느냐에 따라 다양하게 사용 가능하다
int hour = 3;
int minute = 5;
System.out.println(hour + "시간 " + minute + "분");
// 3시간 5분
int totalMinute = (hour*60) + minute;
System.out.println("총 " + totalMinute + "분");
// 총 185분
변수는 서로 교환할 수 없지만 값을 다른 곳에 복사하여 옮기는 방식으로 교환이 가능하다
int x = 3;
int y = 5;
System.out.println("x:" + x + ", y:"+ y);
// x:3, y:5
int temp = x;
x = y;
y = temp;
System.out.println("x:" + x + ", y:"+ y);
// x:5, y:3
변수의 사용범위)
자바의 모든 변수는 중괄호({}) 블록 내에 선언된다. 메소드 블록 내에서 선언된 변수는 로컬 변수라고 하는데, 로컬 변수를 메소드 블록 내부에서만 사용되고 메소드 실행이 끝나면 메모리에서 자동으로 없어진다. 따라서 변수는 자신이 속한 블록 내부에서만 사용이 가능하다. 따라서 자신이 선언된 {} 밖에서는 사용불가로 컴파일 에러가 발생한다.
int v1 = 15;
if(v1>10){
int v2;
v2 = v1 - 10;
}
int v3 = v1 + v2 + 5;
// v2가 블록 밖으로 나와 컴파일 에러
02-2 / 기본 타입 (Primitive Type)
자바의 자료형 타입는 크게 기본 자료형과 참조자료형이 존재한다.
그 중 기본타입은 총 8개이다.
구분 | 저장되는 값에 따른 분류 | 타입의 종류 |
기본타입 | 정수타입 | byte, char, short, int, long |
실수타입 | float, double | |
논리타입 | boolean |
1) 정수 타입
타입 | 메모리사용크기 | 저장되는 값의 허용 범위 | ||
byte | 1byte | 8bit | -2⁷ ~ (2⁷ -1) | -128 ~ 127 |
short | 2byte | 16bit | -2¹⁵ ~ (-2¹⁵ -1) | -32,768 ~ 32,767 |
char | 2byte | 16bit | 0 ~ (2¹⁶ - 1) | 0 ~ 65535 (유니코드) |
int | 4byte | 32bit | -2³¹ ~ (2³¹ - 1) | -2,147,483,648 ~ 2,147,483,647 |
long | 8byte | 64bit | -2⁶³ ~ (2⁶³ - 1) | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 |
정수 리터럴
* 리터럴이란 소스코드에서 프로그래머에 의해 직접 입력된 값을 리터럴 (literal)이라고 한다. 자바가 정수로 인식하는 리터럴 경우는 2진수, 8진수, 10진수, 16진수에 해당한다.
int var1 = 0b1011; // 11
int var2 = 0206; // 134
int var3 = 365; // 365
int var4 = 0xB3; // 179
타입변수가 허용할 수 있는 범위를 넘어서면 컴파일 에러가 발생한다. 돌리기도 전에 경고가 뜬 모습
long 타입은 수치가 큰 데이터를 다루는 프로그램에서 주로 사용.
사용방법은 정수 리터럴 뒤에 소문자 l이나 대문자 L을 붙여 사용하면 된다. 소문자는 1과 헷갈리기 쉬움으로 대문자를 보통 쓴다. 만약 정수 리터럴이 int 범위 내라면 L을 붙이지 않아도 된다.
long var1 = 30000000000000L;
char 타입
char또한 정수타입이다. 하나의 문자를 작은 따옴표(')로 감싼 것을 문자 리터럴이라고 하며 문자 리터럴은 유니코드로 변환되어 저장된다.
*유니코드 : 문자를 숫자를 이용해 표현하도록 정한 표준 중 하나
char var1 = 'A';
char var2 = 65; // A의 유니코드 숫자
char var3 = '\u0041'; // 16진수 유니코드에 해당하는 문자출력
int var4 = 'A'; // int에 문자
System.out.println(var1); // A
System.out.println(var2); // A
System.out.println(var3); // A
System.out.println(var4); // 65
+ String 타입과의 비교) String은 기본타입은 아닌 Reference Type(참조자료형/클래스)이다.
차이점 | |||||
char | 문자 | = 문자 1개 | primitive type | ' (작은 따옴표) | 유니코드로 저장O |
String | 문자열 | = 문자 여러개 | reference type | " (큰 따옴표) | 유니코드로 저장X |
문자열을 ' 작은 따옴표로 감싸거나, 문자를 " 큰 따옴표로 감싸면 컴파일 에러가 난다.
- 이스케이프 문자
문자열 내부에서 사용하는 \ (역슬래시)가 붙은 문자로 이를 사용하면 특정문자를 문자열로 포함시킬 수 있다.
이스케이프 문자 또한 유니코드로 저장되는 char와 동일하다.
ex) \" ( "출력 ) , \' ( '출력 ) , \t (탭만큼 띄움), \n (줄바꿈/Line Feed(LF)) , \\ ( \출력 ) , \u (16진수 유니코드에 해당하는 문자출력) , \r (캐리지리턴 Carriage Return(CR) : 커서를 맨앞으로 이동)
String var1 = "\"안녕\"...\t...\n\'안녕\'...\t...";
System.out.println(var1);
// "안녕"... ...
// '안녕'... ...
2) 실수 타입
소수점이 있는 실수 리터럴을 저장할 수 있는 타입
타입 | 메모리사용크기 | 저장되는 값의 허용 범위 | 정밀도(소수점 이하 자리) | |
float | 4byte | 32bit | (1.4x10⁻⁴⁵) ~ (3.4x10³⁸) | 7자리 |
double | 8byte | 64bit | (4.9x10⁻³²⁴) ~ (1.8x10³⁰⁸) | 15자리 |
소스코드에서 소수점이 있는 숫자 리터럴을 10진수 실수로 인식한다.
또한 알파벳 소문자 e나 대문자 E가 포함되어 있는 숫자 리터럴은 지수와 가수로 표현된 소수점이 이쓴 10진수 실수로 인식한다.
자바는 기본적으로 실수 리터럴을 double 타입으로 해서가기 때문에 double로 저장해야한다. 실수 리터럴을 float에다 저장하면 컴파일 에러발생, float에 넣고 싶다면 리터럴 뒤에 소문자f나 대문자 F를 붙여야한다
float var1 = 3.14; // 컴파일 에러
float var2 = 3.14f; // 3.14
double var3 = 3.14; // 3.14
double var4 = 314e-2; // 3.14
float와 double이 저장되는 값 허용범위가 다르기때문에 표현되는 정밀도 또한 다르다.
float var1 = 0.1234567890123456789f;
double var2 = 0.1234567890123456789;
System.out.println(var1);
System.out.println(var2);
// 0.12345679
// 0.12345678901234568
3) 논리 타입
참과 거짓을 뜻하는 논리 리터럴로 true와 false를 사용
논리 리터럴은 1byte크기의 boolean 타입에 변수를 저장한다.
boolean stop = true;
if(stop){
System.out.println("중지합니다");
} else {
System.out.println("시작합니다");
}
// 중지합니다
02-3 / 타입 변환
타입 변한이란 데이터 타입을 다른 데이터 타입으로 변환하는 것을 말한다.
타입마다 변환에 특징이 있어 되는 것이 있고 안되는 것이 있다.
자동 타입 변환)
말 그대로 자동으로 타입 변환이 일어나는 것을 말한다.
작은 허용 범위의 타입에서 큰 허용 범위의 타입 변하는 것이 가능하며
정수와 실수의 범위 타입 크기를 비교하면 다음과 같다
byte < short < int < long < float < double |
그래서 byte 타입의 변수를 int에 넣는다면 int로 변하는 게 가능하다.
char경우에는 int 타입으로 자동 변환 되면서 유니코드 값이 저장된다.
char는 byte로 변환이 불가하다.
강제 타입 변환)
큰 허용 범위 타입이 작은 허용 범위 타입에 변환 될 수 없지만 큰 허용 범위를 나눠 한 부분만 작은 허용 범위에 담는 것이 가능하다 이것을 강제 타입 변환이라 한다.
ex)
int는 byte보다 큰 허용 범위를 가진다. 그러나 (byte) 캐스팅 연산자를 사용해 byte 타입으로 강제 변환 할 수 있다.
int는 char보다 큰 허용 범위를 가진다. 그러나 (char) 캐스팅 연산자를 사용해 char 타입으로 강제 변환 할 수 있다.
실수 타입은 정수 타입보다 큰 허용 범위를 가지지만 실수를 정수 타입에 넣으면서 소수점 이하 부분이 버려지고 담기게 된다.
int intValue = 44032;
char charValue = (char)intValue;
System.out.println(charValue);
// 가
double longValue = 500.14566;
intValue = (int) longValue;
System.out.println(intValue);
// 500
char charValue1 = 'A';
char charValue2 = 1;
//char charValue3 = charValue1 + charValue2; // 컴파일 에러
int intValue = charValue1 + charValue2;
System.out.println(intValue); // 66
System.out.println((char)intValue); // B
정수 연산에서의 자동 타입 변환)
정수 타입 변수가 산술 연산식에서 피연산자로 사용되면 int타입보다 작은 byte, short 타입의 변수는 int 타입으로 자동 변환되어 연산을 수행한다. 따라서 결과 값도 다시 byte나 short라면 강제 변환을 거쳐야 들어간다.
따라서 애초에 int로 타입이 변환되는 거 int의 변수로 넣어 준다면 타입 변환의 처리가 줄어들면서 실행 성능을 향상 시킬 수 있다.
byte a = 10;
byte b = 20;
short a1 = 40;
short b1 = 50;
// byte c = a + b; // 컴파일 에러
byte c = (byte)(a + b);
// short c1 = a1 + b1; // 컴파일 에러
short c1 = (short)(a1 + b1);
System.out.println(c); // 30
System.out.println(c1); // 90
모든 정수 연산식이 int타입으로 변환되는 것은 아니다. 두 피연산자 중 허용 범위가 큰 타입으로 변환되어 연산 수행
실수 연산에서의 자동 타입 변환)
실수 타입 변수가 피연산자로 사용될 경우 두 피연산자가 동일한 타입이라면 해당 타입으로 연산되나, 피연산자 중 하나가 double이라면 큰 범위인 double에 맞춰 타입이 변환되며 연산 결과 역시 double 타입이 된다.
int와 double사이에서도 마찬가지로 double로 변환
정수를 정수로 나눴을때 결과값은 소수점이 나올까?
그렇지 않다. 자바에서 정수 연산의 결과는 정수가 되기 때문에 결과값을 실수에 넣어도 소수점 이하에 0이외에 다른 수는 나오지 않는다. 그래서 둘 중 하나를 실수 형태로 바꾸어 연산을 한다면 다른 하나도 실수의 형태가되어 실수 값을 내놓는다.
int a = 1;
int b = 2;
float c = a/b;
System.out.println(c); // 0.0
float b1 = 2.0f;
float c1 = a/b1;
System.out.println(c1); // 0.5
float c2 = a/(float)b;
System.out.println(c2); // 0.5
만약 (float) (a/b)를 해서 0.0을 얻는 경우가 있는 데 이때는 a/b가 먼저 연사되어 0이 된 후에 캐스팅 연산자가 적용되기 때문
+ 연산에서의 문자열 자동 타입 변환)
+ 연산자는 모두 숫자일 경우 덧셈 연산을 수행
그러나 하나가 문자열일 경우 나머지 피연산자도 문자열로 자동 변환되어 문자열 결합 연산 수행
int value = 10 + 2 + 8;
String str1 = 10 + "2" + 8;
System.out.println(value); // 20
System.out.println(str1); // 1028
문자열을 기본 타입으로 강제 타입 변환)
프로그램에서 숫자나 true, false지만 문자열인 값을 기본타입으로 변환하는 경우가 많다!
변환타입 | 변환 함수 | 다시 스트링으로 돌리는 함수 | 결과 | |
String | byte | Byte.parseByte(문자열 변수); | String.valueOF(기본타입값); |
String |
short | Short.parseShort(문자열 변수); | |||
int | Integer.parseInt(문자열 변수); | |||
long | Long.parseLong(문자열 변수); | |||
float | Float.parseFloat(문자열 변수); | |||
double | Double.parseDouble(문자열 변수); | |||
boolean | Boolean.parseBoolean(문자열 변수); |
02-4 / 변수와 시스템 입출력
System.out.println("출력 내용");
이 코드에서 System.out은 시스템의 표준 출력 장치를 말한다. 표준 입력 장치라면 반대로 System.in을 사용한다.
모니터로 변수값 출력하기)
우리가 계속 사용해온 System.out.println(리터럴 또는 변수);로 표준 출력장치인 모니터에 출력해왔다.
System. | out. | println(리터럴 또는 변수); |
시스템이 가지고 있는 | 출력 장치로 | 괄호 안의 내용을 출력하고 행을 바꿔라 ln은 line의 줄임말로 행을 바꾸라는 의미 |
출력장치 out은 다음과 같은 메소드 들도 제공한다
메소드 | 의미 |
println(내용); | 괄호 안 내용 출력하고 행 바꾸기 |
print(내용); | 괄호 안의 내용을 출력하기 |
printf("형식문자열", 값1, 값2, ...) | 괄호 안의 첫번째 문자열 형식대로 내용을 출력하기 |
printf()에 대해 좀 더 자세하게 보면 아래와 같은 구성으로 되어 있는데 이는 예시를 통해 이해하자
printf( | " 형식 문자열" | 값1 , 값2, 값3 .... | ); |
% [argument_index$] [flags] [width] [.precision] conversion | 형식화된 문자열에 제공될 내용 | ||
% [값 번호] [-,o] [전체자릿수] [소수자릿수] 변환문자 |
형식화된 문자열 | 설명 | 출력 형태 | |
정수 | %d %6d %-6d %06d |
정수 6자리 정수, 왼쪽 빈 자리 공백 6자리 정수, 오른쪽 빈 자리 공백 6자리 정수, 왼쪽 빈 자리 0채움 |
123 ___123 123___ 000123 |
실수 | %10.2f %-10.2f %010.2f |
소수점 이상 7자리, 소수점 이하 2자리, 왼쪽 빈 자리 공백 소수점 이상 7자리, 소수점 이하 2자리, 오른쪽 빈 자리 공백 소수점 이상 7자리, 소수점 이하 2자리, 왼쪽 빈 자리 0 채움 |
____123.45 123.45____ 0000123.45 |
문자열 | %s %8s %-8s |
문자열 8자리 문자열. 왼쪽 빈 자리 공백 8자리 문자열. 오른족 빈 자리 공백 |
abc _____abc abc_____ |
특수문자 | \t \n %% |
탭(tab) 줄 바꿈 % |
% |
System.out.printf("1.%d \n", 123);
System.out.printf("2.%1$6d, 3.%2$-6d, 4.%3$06d \n", 123, 123, 123); // 숫자와 달러사인으로 값의 순서 표시
System.out.printf("5.%10.2f, 6.%-10.2f, 7.%010.2f \n" , 123.45, 123.45, 123.45);
System.out.printf("8.%s, 9.%8s, 10.%-8s", "abc", "abc", "abc");
System.out.printf("11.\t, 12.\n 13.%%");
// 1.123
// 2. 123, 3.123 , 4.000123
// 5. 123.45, 6.123.45 , 7.0000123.45
// 8.abc, 9. abc, 10.abc 11. , 12.
// 13.%
키보드에서 입력된 내용을 변수에 저장하기)
키보드에 키에도 숫자로 정해져 있는 키코드가 있다.
키코드를 읽기 위해서는 System.in.read()를 이용, int타입의 키코드를 얻는다
System. | in. | read(); |
시스템이 가지고 있는 | 입력장치에서 | 입력된 키코드를 읽어라 |
public class Hello {
public static void main(String[] args) throws Exception{
// throws Exception은 예외처리 코드로 이경우 단순 모니터에 예외 내용만을 출력
int keyCode;
while(true){
keyCode = System.in.read();
System.out.println(keyCode);
if(keyCode == 113){ // keyCode 113은 q를 말함
break;
}
}
}
}
+ 책과 달리 Carriage Return값인 13은 출력되지 않는다 왜지?
System.in.read()은 키코드를 하나씩 읽어 2개 이상의 키조합이 불가 이 단점을 보완한 것이 자바 Scanner 위의 함수와 달리 String 타입의 문자열을 받는다.
import java.util.Scanner;
public class Hello {
public static void main(String[] args) throws Exception{
Scanner scanner = new Scanner(System.in);
String inputData;
while(true){
inputData = scanner.nextLine();
System.out.println("입력된 문자열: \""+ inputData + "\"");
if(inputData.equals("q")){ // q와 동일하면 조건문 실행
break;
}
}
System.out.println("종료");
}
}
+Tip |
* sout 이라고 치면 System.out.println(); 소스가 자동완성 된다. |
'Programming > Java' 카테고리의 다른 글
혼공자바] 04-1 조건문과 반복문 (0) | 2022.11.10 |
---|---|
혼공자바] 03 연산자 (0) | 2022.11.08 |
intelliJ] error: unmappable character for encoding MS949 (0) | 2022.10.19 |
IDE] java IDE 종류 2 : intelliJ IDEA 설치 (0) | 2022.10.10 |
JDK] JDK 종류 3 : Azul zulu 설치 (0) | 2022.10.10 |