부산정보산업진흥원과 메가존 클라우드에서 진행하는 "클라우드 네이티브 애플리케이션 개발자 양성과정"에 최종 합격되어 교육과정에서 배우는 과목들 중 하나인 자바 기초를 정리하려고 합니다.
자바 교과에서 사용하는 서적은 한빛미디어의 혼자 공부하는 자바입니다.
변수란?
- 값을 저장할 수 있는 메모리의 특정 번지에 붙이는 이름
- 하나의 변수에 하나의 값만 저장
변수 선언 방법
- 변수에 어떤 타입의 데이터를 저장할 것인지와 변수의 이름을 무엇으로 할것인지 결정
- 형태
int a;
변수 이름 규칙
-
첫번째 글자는 문자 or '$', '_'로 시작해야함.
-
영어 대소문자 구분.
-
자바 예약어는 사용 못함.
-
여러단어를 사용할 시 첫 단어의 첫 문자는 소문자, 이후 단어의 첫문자는 대문자로 사용(관례)
ex) maxSpeed와 같은 형식
※ 예약어 : 해당 프로그래밍 언어에서 의미를 갖고 사용되고 있는 단어
변수 사용 범위
- 자바에서 모든 변수는 중괄호 블록 내에서 선언되고 사용
- 로컬 변수(local variable) : 메소드 블록 내부에서만 사용, 메소드가 끝나면 자동으로 삭제
- 전역 변수(global variable) : 메소드 블록 외부에서 선언, 어디에서든 접근할 수 있는 변수
대입연산자
- 형태
int score;
score = 10;
- 초기화 되지 않은 상태로 해당 변수를 사용하면 컴파일 에러 발생.
타입
- 리터럴(literal) : 소스코드에서 프로그래머에 의해 직접 입력된 값
- byte 타입
- 크기 : 1byte / 범위 : -128 ~ 127
- 변환 함수 : Byte.parseByte(value)
- short 타입
- 크기 : 2byte / 범위 : -32768 ~32767
- 변환 함수 : Short.parseShort(value)
- char 타입
- 크기 : 2byte / 범위 : 0 ~ 65535
- 입력된 문자 리터럴('')은 유니코드로 변환되어 저장.
- int 타입
- 크기 : 4byte / 범위 : -2147483648 ~ 2147483647
- 변환 함수 : Integet.parseInt(value)
- long 타입
- 크기 : 8byte / 범위 : -9223372036854775808 ~ 9223372036854775807
- long 변수에 값을 넣을 때 값에 L을 붙여준다.
ex) long a = 100000000L
- 변환 함수 : Long.parseLong(value)
- String 타입
- 문자열 리터럴("")를 통해 데이터 저장
- 문자열 리터럴로 감싼 데이터는 유니코드로 변환 X
- 문자열 내부에서 이스케이프 문자(\)를 이용해 여러 특정 문자를 표시 할 수 있음.
- 문자열에서 '+' 연산은 문자열 결합 연산
- 문자열을 비교하려면 equals() 메소드를 사용
- float 타입
- 크기 : 4byte / 범위 : 1.4 10^-45 ~ 3.4 10^38
- 소수점 이하 7자리까지 허용, 이후 부터는 오차 발생
- 변환 함수 : Float.parseFloat(value)
- double 타입
- 크기 : 8byte / 범위 : 4.9 10^-324 ~ 1.8 10^308
- 실수 리터럴은 기본적으로 double타입으로 해석, float로 해석하려면 값에 f, F를 붙여준다.
- 소수점 이하 15자리까지 허용, 이후 부터 오차 발생
- 변환 함수 : Double.parseDouble(value)
- boolean 타입
- 참(true)/거짓(false)을 판별할 때 사용
- 변환 함수 : Boolean.parseBoolean(value)
타입 변환
- 자동 타입 변환
- 값의 허용 범위가 작은 타입이 허용 범위가 큰 타입으로 저장할 때 발생
- 정수 타입을 실수 타입에서 저장할 때는 무조건 타입 변환 발생
- byte타입을 char타입으로 변환 불가능
(byte는 음수까지 표현하고 char는 음수를 표현하지 않기 때문)
- 강제 타입 변환
- 큰 허용 범위 타입을 작은 허용 범위 타입으로 강제로 저장하는 것
- 형태
작은 허용 범위 타입 변수명 = (작은 허용 범위 타입) 큰 허용 범위 타입
- 실수 타입의 경우 정수 타입으로 강제 타입 변환을 하면 정수 부분만 저장됨.
단항 연산자
- 부호 연산자 (+, -)
- 양수 및 음수를 표시, boolean타입과 char타입은 제외
- 부호 연산자의 결과는 int 타입
- 증감 연산자 (++, --)
- 피연산자의 값을 1 증가/감소시킴.
- a++ 이면 연산을 수행한 후 1을 증가, ++a 이면 연산을 수행하기 전 1을 증가
- 논리 부정 연산자 (!)
- true를 false로, false를 true로 변경, Boolean타입에서만 사용
- 조건문/반복문의 조건에서 많이 사용
이항 연산자
- 산술 연산자 (+, -, *, /, %)
- 사칙 연산과 나머지 연산을 수행, Boolean타입은 제외
- 피연산자가 byte, short, char 타입일 경우 int타입으로 변환한 후 연산 수행
- 피연산자가 모두 정수 타입이고 long타입이 포함, 모두 long타입으로 변환 후 연산 수행
- 피연산자 중 실수 타입이 있을 경우, 실수 타입으로 변환 후 연산 수행
- char 타입도 산술 연산 가능, int타입으로 변환되어 연산되므로 결과가 int타입으로 반환되는 부분 주의
- 문자열 결합 연산자 (+)
- 비교 연산자 (<, <=, >, >=, ==, !=)
- 피연산자의 대소/동등을 비교해 참/거짓을 판별
- double타입과 float타입을 비교하면 flase로 판별, 부동 소수점 방식으로 실수값을 근사값으로 표현하기 때문.
- 논리 연산자(&&, ||, |, ^, !)
- 논리곱, 논리합, 베타적 논리합, 논리 부정 연산을 수행
- 피연산자는 모두 Boolean타입만 사용
- &&(||)와 &(|)의 차이점은 &&(||)는 왼쪽부터 피연산자를 판별하며 false(true)가 하나라도 나온다면 이후 피연산자는 판별하지 않고 false(true)를 산출, &(|)는 모든 피연산자를 판별한 후 결과를 산출
- 대입 연산자 (=, +=, -=, *=, /=, %=)
- 오른쪽 피 연산자의 값을 왼쪽 피연산인 변수에 저장
삼항 연산자
- 3개의 피연산자를 필요로 하는 연산자를 말함.
- 형태 : 조건 ? 참일 때 반환 값 : 거짓일 때 반환 값
조건문
- if문
- 조건식을 통해 블록 실행 여부 결정
- 형태
if(조건식){
실행 코드
}
- if - else문
- 조건식이 참이면 if문 블록 실행, 거짓이면 else문 블록 실행
- 형태
if(조건식){
참일 때 실행 코드
}else{
거짓일 때 실행코드
}
- if - else if - else문
- 조건이 여러개일 때 사용하는 조건문
- 형태
if(조건식1){
조건식 1이 참일 때 실행 코드
} else if(조건식2){
조건식 2가 참일 때 실행 코드
}
else{
모두 거짓일 때 실행코드
}
- switch문
- 변수의 값을 통해 실행문이 선택
- 형태
switch(변수){
case 값1:
실행문1;
break;
case 값2:
실행문2;
break;
default:
default 실행문;
}
반복문
-
for문 - 1
- 형태
for(초기화식 ; 조건식 ; 증감식){
실행문;
}
- 실행 순서
- for문이 실행되며 초기화식 실행
- 조건식을 통해 true이면 내부 코드 실행, false이면 for문 탈출
- 내부 코드 실행 후 증감식 실행, 다시 조건식 판별
- 조건이 false일 때까지 2번과 3번과정 반복
-
for문 - 2
- 형태
for(타입 변수 : 배열){
실행문;
}
- 실행 순서
- for문이 실행될 때 배열에서 가져올 첫 번째 값이 존재하는지 체크
- 가져올 값이 존재하면 변수에 저장
- 실행문 실행
- 배열에서 가져올 다음 값이 존재하는지 체크
- 가져올 다음 항목이 없을 때까지 4번 - 2번 - 3번 과정 반복
-
while문
- 형태
while(조건식){
실행문;
}
- 실행 순서
- while문이 실행되며 조건식 판별
- 조건식을 통해 true이면 내부 코드 실행, false이면 for문 탈출
- 내부 코드 실행 후 조건식 판별
- 조건이 false일 때까지 2번과 3번과정 반복
-
do-while문
- 형태
do{
실행문;
}
while(조건식)
- 실행 순서
- do-while문이 실행되며 실행문을 실행
- 내부 코드 실행 후 조건식 판별
- 조건이 false일 때까지 2번과 3번과정 반복
참조 타입과 참조 변수
- 배열
- 같은 타입의 데이터를 연속된 공간에 나열, 각 데이터에 인덱스를 부여해놓은 자료구조
- 생성된 배열은 길이를 늘리거나 줄일 수 없음.
- 배열 생성 방법
- 타입[] 변수명 = new 타입[길이];
- 타입 변수명[] = new 타입[길이];
- 배열 사용 방법 : 변수명[인덱스]
- 유용한 함수
- 배열 변수.length : 배열의 길이를 가져옴.
- 다차원 배열
- 2차원 이상의 배열로 구성된 배열을 다차원 배열이라 부름.
열거
- 열거 타입
- 한정된 값인 열거 상수 중에서 하나의 상수를 저장하는 타입
- 선언 방식
public enum 열거타입이름 {
열거상수1,
열거상수2,
}
- 열거 상수
- 열거 타입 선언 때 주어진 상수
- 사용 방법 : 열거타입.열거상수
객체 지향 프로그래밍
- 객체
- 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있으면서 식별 가능한 것
- 객체들 사이의 상호작용 수단은 메소드
- 객체 모델링
- 현실 세계의 객체를 소프트웨어 객체로 설계하는 것
- 객체 간의 관계
- 집합 관계 : 어떤 객체는 부품 역활, 다른 객체는 완성품 역활을 하는 경우
- 사용 관계 : 객체 간의 상호작용하는 경우
- 상속 관계 : 상위 객체를 기반으로 하위 객체를 생성하는 관계
클래스
- 클래스란?
- 객체를 생성하기 위한 필드와 메소드가 정의되어 있는 설계도.
- 아직 클래스 객체는 생성되지 않은 상태이고, new 키워드를 이용해 클래스 객체 생성
- 클래스 선언 및 생성 형식
public class 클래스명 (){
클래스명 변수명 = new 클래스명();
}
- 클래스의 구성 멤버
- 필드
- 형태 : 타입 필드명 = 초기값; (초기값 생략가능)
- 객체의 고유 데이터를 저장하는 곳
- 생성자와 메소드 전체에서 사용되며 생성자와 메소드 블록 내부에서 선언된 것은 모두 로컬 변수
- 객체가 삭제되지 않는 한 객체에 존재
- 사용방법
- 클래스 변수에 해당 클래스 객체 생성
- 해당 클래스 변수에 도트 연산자(.)을 이용해 필드에 접근
※ 도트 연산자(.)는 객체 접근 연산자로 객체가 가지고 있는 필드나 메소드를 사용할 때 이용됨.
- 생성자
- 형태 : 클래스명(매개변수1, ...) {객체 초기화 코드}
- 매개변수는 0개 이상이며, 매개변수 개수 및 타입이 다르면 다른 생성자로 취급(오버로딩).
- this는 객체 자신 참조, this(매개변수, ..)를 이용해 생성자 안에서 다른 생성자를 호출 할 수 있다. 그리고 this는 생성자 첫 줄에서만 허용
- 모든 클래스는 생성자가 반드시 존재, 하나 이상 가질 수 있음.
- 생성자 선언을 생략했다면 기본 생성자를 자동으로 추가해줌.
- 객체를 생성할 때 반드시 호출되는 메소드
- 객체 생성 시 초기화
- 리턴 타입이 없고, 메소드명이 클래스 이름으로 되어 있음.
- 메소드
- 객체 간의 데이터를 전달하는 수단
- 메소드 선언부(리턴 타입, 메소드 이름, 매개변수선언, 메소드 실행 블록)와 실행 블록으로 구성
- 리턴 타입
- 메소드 이름
- 숫자로 시작X, $와 _ 이외의 특수문자X
- 여러단어가 홈합된 이름이면 뒤이어 오는 단어의 첫 글자는 대문자로 작성
- 매개변수선언
- 메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용
- 매개 변수의 개수를 모를 경우 배열과 같은 타입으로 매개변수를 넘김.
- 리턴문
- 리턴값이 있는 메소드일 경우 반드시 리턴문을 사용해 리턴값을 지정
- 리턴값은 리턴 타입이거나 리턴 타입으로 형변환을 할수 있아야함.
- 리턴값이 없는 메소드
- 리턴 타입으로 void를 사용
- return;를 사용하면 메소드 실행을 강제 종료 시킴.
- 메소드 호출
- 클래스 객체를 생성하여 도트 연산자를 이용해 메소드 호출
- 클래스 내부에서는 해당 메소드를 사용하면됨.
- 생성자 오버로딩과 마찬가지로 메소드도 오버로딩을 할수있다.
- 오버로딩시 매개변수의 개수나 타입, 순서중 하나라도 달라야함.
- 인스턴스 멤버
- 클래스 객체를 생성한 후 사용할 수 있는 필드(인스턴스 필드)와 메소드(인스턴스 메소드)
- this란?
- 객체 내부에서 인스턴스 멤버에 접근하기 위해 사용
- 매개변수 이름과 필드의 이름이 동일한 경우, 인스턴스 멤버인 필드를 명시하고자 사용
- 정적 멤버
- 클래스에 고정된 멤버
- 객체를 생성하지 않고 사용할 수 있는 필드(정적 필드)와 메소드(정적 메소드)
- 필드와 메소드 선언할 때 static 키워드를 추가
- 객체마다 가지고 있을 필요가 없는 공용 데이터이면 정적 필드로 선언
- 정적 메소드는 인스턴스 필드를 포함 여부에 따라 선언.
- 도트 연산자를 통해 정적 멤버에 접근
- 정적 메소드 선언 시 주의 사항
- 인스턴스 필드나 인스턴스 메소드를 사용못함.
- this 키워느도 사용못함.
- 인스턴스 멤버에 접근하려면 객체를 생성한 후 접근가능.
- 싱글톤
- 단 하나의 객체만 만들도록 보장 해야하는 경우 사용하는 디자인 패턴
- final 필드
- 초기값이 저장되면 이것이 최종적인 값이 되어 프로그램 실행 도중 수정할 수 없음.
- 초기화 방법
- 초기화 하지 않으면 컴파일 에러 발생
- 객체마다 값이 저장되고 생성자를 통해 여러가지 값을 가질 수 있어 상수가 아님.
- 상수
- 불변의 값을 저장하는 필드
- static final 필드를 통해 상수 선언
- 객체마다 존재하지 않고 클래스에만 존재
- 하번 초기값이 저장되면 변경 불가
- 패키지
- 클래스를 유일하게 만들어주는 식별자 역활
- 이름이 같은 클래스라도 패키지가 다르면 다른 클래스로 인식
- import문
- 패키지의 클래스 또는 인터페이스를 가져와 사용할 것임을 컴파일러에게 알려줌.
- 상위 패키지를 import해도 하위 패키지까지 import되는 것은 아님.
- 접근 제한자
- 클래스 및 인터페이스, 멤버의 접근을 제한하기 위해 사용
- public 접근 제한자
- protected 접근 제한자
- private 접근 제한자
- default 접근 제한자
- Getter와 Setter 메소드
- 객체 지향 프로그래밍에서 객체 필드를 외부에서 직접적으로 접근하는 것을 막는다. 이유는 마음대로 변경하면 객체의 무결성이 깨질 수 있음.
- Setter 메소드
- 메소드를 통해 필드에 접근 유도
- 매개값을 검증해서 유효한 값만 필드에 저장
- Getter 메소드
- 필드값을 직접사용하면 부적절한 경우가 있기 때문에 메소드를 통해 필드값을 가공한 후 외부로 전달
상속
- 상속
- 이미 개발된 클래스를 재사용하여 중복되는 코드를 줄여줌.
- extends 키워드를 이용해 상속을 받음.
- 상속의 특징
- 여러 개의 부모 클래스를 상속받을 수 없음.
- 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외
- 부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 메소드도 상속 대상에서 제외
- 상속 받은 자식 클래스가 생성될 때 부모 클래스부터 생성된 후 자식 클래스가 생성되어 기본 생성자가 있는 경우 부모 클래스 기본 생성자가 먼저 호출된 후 자식 클래스 기본 생성자가 호출됨.
- super 키워드를 이용해 부모클래스의 생성자를 호출 가능, 자식 생성자의 맨 첫 줄에 위치해야함. 아니면 컴파일 에러
- 메소드 재정의(메소드 오버라이딩)
- 상속된 일부 메소드를 자식 클래스에서 다시 수정해서 사용하는 것
- 메소드 재정의 규칙
- 부모의 메소드와 동일한 타입, 이름, 매개변수 목록을 가져야함.
- 접근 제한을 더 강하게 재정의할 수 없습니다.
- 새로운 예외를 throws할 수 없습니다.
- 부모 메소드 호출
- 명시적으로 super키워드와 도트연산자를 이용해 부모 메소드를 호출
- final 클래스
- 클래스를 선언할 때 final 키워드를 붙이면 최종적인 클래스이므로 상속할 수 없는 클래스
- 부모 클래스가 될 수 없으며 자식 클래스를 만들 수 없다.
- final 메소드
- 부모 클래스를 상속해서 자식 클래스를 선언할 때 final로 선언된 메소드는 자식 클래스에서 재정의할 수 없음.
다형성과 타입 변환
- 다형성
- 사용 방법은 동일, 다양한 객체를 이용해 다양한 실행 결과가 나오도록하는 성질
- 필드의 다형성
- 필드 타입을 부모 타입으로 선언, 다양한 자식 객체들이 저장 가능
- 다양한 자식 객체로 인해 필드 사용 결과가 달라질 수 있음.
- 매개 변수의 다형성
- 매개변수를 부모 타입으로 선언하여 자식 객체들도 매개값으로 사용 가능
- 타입 변환
- 타입을 다른 타입으로 변환하는 행위
- 자동 타입 변환
- 프로그램 실행 도중 자동으로 타입 변환이 일어나는 것
- 자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급가능
- 강제 타입 변환
- 부모 타입을 자식 타입으로 변환하는 것
- 자식 타입이 부모타입으로 타입 변환 후 다시 자식 타입으로 변환할 때 사용
- instanceof 연산자를 통해 객체 타입을 확인하고 강제 타입 변환을 진행
추상 클래스
- 추상 클래스
- 객체를 생성할 수 있는 실체 클래스의 공통적인 특성을 추출해서 선언한 클래스를 추상 클래스라고 함.
- 실체 클래스와 상속 관계, 실체 클래스가 추상 클래스의 모든 특성(필드와 메소드)를 물려받고, 추가적인 특성을 가짐.
- 추상 메소드 선언 가능
- 선언 형식
public abstract class 클래스{
}
- 추상 클래스의 용도
- 공통된 필드와 메소드의 이름을 통일할 목적
- 실체 클래스를 작성할 때 시간 절약
- 추상 메소드
- abstract 키워드와 함께 메소드의 선언부만 있고 메소드 실행 블록이 없는 메소드
- 형태 : 접근제한자 abstract 리턴타입 메소드타입(매개변수, ...)
- 자식 클래스에서 반드시 추상 메소드를 재정의
인터페이스
- 인터페이스
- 다른 클래스를 작성할 때 기본이 되는 틀을 제공
- 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스
- 선언 형식
public interface 인터페이스명{
타입 상수이름 = 값;
타입 메소드이름(매개변수, ...);
}
- 인스턴스 또는 정적 필드를 선언할 수 없고, 고정된 값인 상수 필드는 선언 가능하며 선언과 동시에 초기값을 지정해야함.
- 인터페이스에서 메소드는 추상 메소드로 선언
- 구현 객체는 인터페이스에서 정의된 추상 메소드들을 실체 메소드로 가지고 있어야함.
- 구현 클래스
- 인터페이스 타입을 사용한다는 것을 알려주기 위해 implement키워드를 사용]
- 선언 형식
public class 구현 클래스이름 implement 인터페이스명1, ...{
}
- 다중 상속을 지원하지 않지만 인터페이스를 통해 다중 상속 기능을 지원
- 인터페이스 다형성
- 소스 코드는 동일, 구현 객체를 교체해 실행결과가 다양해지는 것
중첩 클래스
- 중첩 클래스
- 클래스 내부에 선언한 클래스
- 두 클래스의 멤버들을 서로 쉽게 접근
- 불필요한 관계 클래스를 감춰 코드 복잡성을 줄임.
- 멤버 클래스
- 클래스의 멤버로 선언된 중첩 클래스
- 클래스나 객체가 사용 중이라면 언제든지 재사용 가능
- 인스턴스 멤버 클래스
- static 키워드 없이 중첩 선언된 클래스
- 인스턴스 필드와 메소드만 선언 가능
- 정적 멤버 클래스
- static 키워드로 선언된 클래스
- 모든 종류의 필드와 메소드를 선언
- 로컬 클래스
- 생성자 또는 메소드 내부에서 선언되는 중첩 클래스
- 메소드를 실행할 때만 사용, 메소드가 종료되면 없어짐.
- 접근 제한자및 static을 붙일 수 없음.
- 인스턴스 필드와 메소드만 선언 가능
- 중첩 클래스 접근 제한
- 바깥 필드와 메소드에서 사용 제한
- 인스턴스 멤버 클래스는 정적 필드와 정적 메소드 객체를 생서하지 못함.
- 정적 멤버 클래스는 모든 필드나 모든 메소드를 객체로 생성할 수 있음.
- 멤버 클래스에서 사용 제한
- 인스턴스 멤버 클래스 안에서는 바깥 클래스의 모든 필드와 모든 메소드에 접근 가능
- 정적 멤버 클래스 안에서 바깥 클래스의 정적 필드와 정적 메소드만 접근 가능
- 로컬 클래스에서 사용 제한
- 메소드의 매개변수나 로컬 변수를 로컬 클래스에서 사용할 때 제한
- 중첩 클래스에서 바깥 클래스 참조 얻기
- 클래스 내부에서 this는 객체 자신의 참조
- 바깥클래스.this.필드/메소드()로 접근 가능
- 중첩 인터페이스
- 해당 클래스와 긴밀한 관계를 맺는 구현 클래스를 만들기 위해 사용.
- 인스턴스 멤버 인터페이스
- 정적 멤버 인터페이스
- 바깥 클래스의 객체 없이 바깥 클래스만으로 바로 접근
- UI프로그래밍에서 이벤트 처리 목적으로 많이 활용
-
익명 객체
- 이름이 없는 객체로 클래스를 상속하거나 인터페이스를 구현할 때 사용
- 선언 형식
부모클래스 변수 = new 부모클래스() { ... }
인터페이스 변수 = new 인터페이스() { ... }
-
익명 자식 객체
- 자식 클래스가 재사용되지 않고 오로지 특정 위치에서 사용하는 경우 자식 클래스를 명시적으로 선언하지 않고 익명 자식 객체를 생성하여 사용
- 생성자를 선언할 수 없는 특징을 가지고 있음.
- 형태
부모클래스 필드/변수 = new 부모클래스(매개값, ...){
}
-
익명 구현 객체
- 특정 위치에서 사용할 경우 익명 구현 객체를 이용
- 익명 구현 객체 내 인터페이스에 선언된 추상 메소드의 실체 메소드를 재정의해야함.
- 형태
인터페이스 필드/변수 = new 인터페이스(){
}
예외
- 예외 클래스로 java.lang.Exception 클래스가 존재
- 일반 예외
- 프로그램 실행 시 예외가 발생할 가능성 높아 컴파일 과정에서 해당 예외 처리 코드가 있는지 체크, 없으면 컴파일 에러
- 실행 예외
- 프로그램 실행 시 예측할 수 없이 갑자기 발생 컴파일 과정에서 예외 처리 코드가 있는지 처크 안함.
- 오로지 개발자의 경험에 의해 예외 처리 코드 작성됨.
- 예외 종류
- NullPointerException : 참조한 객체가 없는 참조 변수에 접근했을 때 발생
- ArrayIndexOutOfBoundsException : 배열 인덱스 범위를 초과했을 때 발생
- NumberFormatException : 숫자로 변환할 수 없는 문자가 포함되어있을 때 발생
- ClassCastException : 대입된 클래스의 객체가 아닌 다른 클래스 타입으로 타입 변환 했을 때 발생
- 예외처리
- try-catch-finally 구문
try{
실행문 1
}
catch(예외클래스 e1){
실행문 2
}
catch(예외클래스 e2){
실행문 3
}
finally{
실행문 4
}
- 실행 순서
- try문의 실행문 1을 실행.
- 실행문 1에서 예외가 없으면 catch문의 실행문2 뛰어넘고 finally문의 실행문3 실행
실행문 1에서 예외가 발생하면 catch문의 실행문2 실행하고 finally문의 실행문3 실행
- throws 키워드
- 메소드 선언부 끝에 작성되어 메소드에서 처리하지 않은 예외를 호출한 곳으로 떠넘기는 역활
기본 API 클래스
- API(application Programming Interface)란?
- 라이브러리라 부르기도 하고, 프로그램 개발에 자주 사용되는 클래스 및 인터페이스 모음
-
Object 클래스
- 클래스를 선언할 때 암시적으로 Object 클래스 상속
- 최상위 부모 클래스로 모든 클래스는 Object 클래스의 자식이거나 자손 클래스
- 사용할 수 있는 메소드
- equals() : 비교 연산자 '=='과 동일한 결과 리턴, 동등 비교할 대 많이 사용
- hashCode() : 객체를 식별하는 하나의 정수값
- toString() : 객체의 문자 정보 리턴
-
System 클래스
- 운영체제의 일부 기능 이용 가능
- System 클래스의 모든 필드와 메소드가 정적 필드와 정적 메소드로 구성
- 사용 할 수 있는 메소드
- exit() : 강제적으로 JVM 종료
- currentTimeMillis() : 현재 시간을 읽어서 밀리세컨드 단위의 long값으로 반환
- nanoTime() : 현재 시간을 읽어서 나노세컨드 단위의 long값으로 반환
- Class 클래스
- 클래스와 인터페이스의 메타 데이터를 관리
- 사용할 수 있는 메소드
- getClass()/forName() : 클래스 이름을 이용해 클래스 객체를 얻는 방법
- getResource(상대경로) : 클래스를 기준으로 상대경로를 이용해 절대 경로를 얻음.
- Wrapper 클래스
- 기본 타입의 값을 갖는 객체를 포장 객체라 함.
- 기본 타입의 값을 객체 내부에 두고 포장하기 때문
- 포장하고 있는 기본 타입 값은 외부에서 변경할 수 없음.
- 박싱(Boxing)
- 기본 타입의 값을 포장 객체로 만드는 과정
- 포장타입 변수명 = new 포장(값)
- 포장타입 변수명 = 포장타입.valueOf(값)
- 언박싱(Unboxing)
- 포장 객체에서 가본 타입의 값을 얻어내는 과정
- 기본타입 변수명 = 포장타입변수.기본타입Value()
- Math 클래스
- 수학 계산에 이용할 수 있는 메소드 제공
- 사용할 수 있는 메소드
- abs(값) : 절대값
- ceil(값) : 올림값
- floor(값) : 버림값
- max(값1, 값2) : 최대값
- min(값1, 값2) : 최소값
- random() : 랜덤값
- rint(값) : 가까운 정수의 실수값
- round(값) : 반올림값
스레드
- 프로세스
- 운영체제로부터 실행에 필요한 메모리를 할당받아 애플리케이션의 코드를 실행하는 것
- 하나의 애플리케이션에서 여러개의 프로세스를 실행할 수 있다.
(멀티 프로세스)
- 메모리를 가지고 실행, 서로 독립적
- 스레드
- 프로그램 내에서 실행되는 프로그램 제어 흐름
- 스레드가 1개이면 단일 스레드, 2개이상이면 멀티 스레드
- 프로그램을 실행하는 주체
- setName(이름)으로 스레드 이름 설정
- getName()으로 스레드 이름 가져오기
- 멀티 스레드
- 하나의 프로세스가 두개 이상의 스레드를 이용해 작업을 처리하는 것을 의미
- 하나의 스레드가 예외를 발생시키면 프로세스 자체가 종료될 수 있음.
- 프로그램을 개발하는 데 꼭 필요한 기능
- 메인 스레드
- main() 메소드의 첫 코드부터 아래로 순차적으로 실행, 마지막 코드가 실행되거나 return문을 만나면 실행이 종료
- 반드시 존재함.
- 작업 스레드
- 작업 스레드도 객체로 생성하므로 java.lang.Thread클래스 이용함.
- 직접 생성하는 방법
Thread thread = new Thread(Runnable target)
class 클래스명 implements Runnable{
public void run(){
스레드가 실행할 코드;
}
}
thread.start()
- 하위 클래스로부터 생성
public class 클래스명 extends Thread{
@Override
public void run(){
스레드가 실행할 코드;
}
}
- 데몬 스레드
- 주 스레드의 작업을 돕는 보조적인 역할을 수행하는 스레드
- 주 스레드가 종료되면 같이 종료됨.
- start() 메소드 앞에서 setDaemon(참/거짓) 메소드가 실행되야함.
- isDaemon() 메소드를 이용해 데몬 스레드인지 판별
- 동기화 메소드
- 스레드가 사용중인 객체를 다른 스레드가 변경할 수 없도록 하기 위해 사용하는 객체를 잠가 다른 스레드가 이용할 수 없게함.
- 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드 영역을 임계영역이라함.
- 자바에서 임계 영역을 지정하기 위해 동기화 메소드 제공
- synchronized 키워드를 붙여 동기화 메소드로 지정
- 형태
public synchronized void 메소드명(){
임계 영역
}
- 스레드 상태
- 실행 대기 상태 : 스레드 객체 생성 후 start() 메소드 호출
- 실행 상태 : 운영체제가 실행할 스레드를 선택하여 run() 메소드를 실행
- 종료 상태 : 더 이상 실행할 코드가 없는 상태
- 스레드 상태 제어
- 실행 중인 스레드 상태를 변경하는 것
- 스레드 상태 제어 메소드
- interrupt() : 일시 정지 상태의 스레드에서 InterruptedException을 발생시켜 예외처리 코드에서 실행 대기 상태나 종료 상태로 갈 수 있도록 함. 실행 상태에서 바로 예외를 발생하지 않고 일시 정지 상태가 되면 예외 발생
- sleep(시간) : 주어진 시간 동안 스레드 일시 정지 상태로 만듬. 시간이 지나면 자동으로 실행 대기 상태가됨.
- stop() : 스레드를 즉시 종료
- stop() 메소드를 사용할 때 스레드를 안전하게 종료시키는 방법
- stop 플레그를 이용 : 플래그 변수를 이용해 실행 코드 블록에 접근하게 하고, 실행 코드 블력 외부에는 사용한 자원을 정리
- interrupt() 메소드 이용 : interrupt() 메소드를 이용해 InterruptedException 예외를 발생시켜 catch문에서 사용한 자원 정리
컬렉션 프레임워크
-
리스트(List)
- 배열과 비슷하게 객체를 인덱스로 관리
- 배열과 차이점 : 리스트의 길이가 자동으로 증가, 객체를 저장할 때 자동으로 인덱스가 부여
- 객체의 주소를 참조
- 리스트 컬렉션 종류 : ArrayList, Vector, LinkedList 등
- 객체 추가
- boolean add(인덱스) : 맨 끝에 객체 추가
- void add(인덱스, 값) : 인덱스 위치에 객체 추가
- set(인덱스, 값) : 인덱스 위치에 저장된 객체를 값으로 변경
- 객체 겸색
- contains(객체) : 객체가 저장되어 있는지 조사
- get(인덱스) : 해당 인덱스에 저장된 객체 반환
- isEmpty() : 컬랙션 객체가 비어있는지 조사
- size() : 컬랙션 객체에 저장된 객체 수를 반환
- 객체 삭제
- clear() : 컬랙션 객체에 저장된 객체 전부 삭제
- remove(인덱스) : 인덱스 위치에 저장된 객체 삭제
- remove(객체) : 주어진 객체 삭제
- ArrayList
- 형태
(Array)List<타입> 리스트변수 = new ArrayList<타입>();
- 특정 인덱스에 객체를 추가하거나 삭제할 때 특정 인덱스 이후 값들의 인덱스가 1씩 당겨지거나 밀려나기 때문에 삽입/삭제가 빈번히 일어나는 곳에서는 부적절함.
- 인덱스를 이용해 객체를 찾거나 마지막에 객체를 추가하는 경우 좋은 성능을 발휘
- vector
- 형태
List<타입> 리스트변수 = new Vector<타입>();
List<타입> 리스트변수 = new Vector<>();
- ArrayList와 동일한 내부 구조
- 동기화된 메소드로 구성되어 멀티 스레드에서 동시에 vector 메소드를 실행할수 없음.
- 하나의 스레드가 vector 메소드 실행을 완료하면 다른 스레드가 vector 메소드를 실행하므로 멀티 스레드 환경에서 안전하게 객체를 추가/제거 가능
- LinkedList
- 형태
List<타입> 리스트변수 = new LinkedList<타입>();
List<타입> 리스트변수 = new LinkedList<>();
- ArrayList와 사용방법은 동일, 내부구조는 완전히 다름
- 인접 참조를 링크해서 체인처럼 관리
- 객체를 삽입/삭제할때 앞뒤 링크(포인터)만 변경
- 삽입/삭제가 빈번한 곳에서 좋은 성능을 발휘
-
set 컬렉션
- 순서 상관없이 중복을 허용하지 않음.
- set 컬렉션 종류 : HashSet, LinkedHashSet, TreeSet 등
- 객체 추가
- 객체 검색
- contains(객체) : 객체가 있는지 조사
- isEmpty() : 컬렉션이 비었는지 조사
- iterator() : 저장된 객체를 하나식 가져옴
- size() : 컬렉션에 저장된 객체 개수 가져옴
- 객체 삭제
- clear() : 컬렉션에 저장된 객체 전부 삭제
- remove(객체) : 주어진 객체를 삭제
- 반복자(Iterator) 인터페이스를 이용해 객체 하나씩 가져옴.
- Iterator 인터페이스 메소드
- hasNext() : 가져올 객체가 있는지 체크
- next() : 컬렉션에서 하나의 객체를 가져옴
- remove() : 컬렉션에서 객체를 제거
- HashSet
- 형태
Set<타입> set = new HashSet<타입>()
- 객체들을 순서 없이 저장, 동일한 중복 객체는 저장X
- 1차적으로 hashCode() 메소드를 통해 객체의 해시코드를 얻고, 저장되어있는 객체들의 해시코드와 비교해서 중복 객체를 체크, 동일한 해시코드가 있으면 equals() 메소드를 통해 객체 비교
- Map 컬렉션
- 키와 값으로 구성된 객체를 저장
- 키는 중복X, 값은 중복O
- Map 컬렉션 종류 : HashMap, Hashtable, LinkedHashMap, Properties, TreeMap 등
- 객체 추가
- 객체 검색
- containsKey(키) : 해당 키가 있는지 체크
- containsValue(값) : 해당 값이 있는지 체크
- get(키) : 해당키의 값을 리턴
- isEmpty() : 컬렉션이 비어있는지 체크
- keySet() : 모든 키를 Set 객체에 담아서 반환
- size() : 컬렉션 키의 개수 반환
- values() : 저장된 모든 값을 Collection에 담아서 반환
- 객체 삭제
- clear() : 컬렉션의 키와값을 전부 삭제
- remove(키) : 주어진 키와 일치하는 키와 값을 삭제
- HashMap
- 형태
Map<키타입, 값타입> 변수명 = new HashMap<키타입, 값타입>()
- 이름 그대로 해싱(hashing)된 맵
- 해싱(hashing) : 키에 산술적인 연산을 적용하여 항목이 저장된 테이블 주소를 계산해서 접근
- 키는 맵에서 오직 하나만, 값은 중복된 값이여도 상관없음
- Hashtable
- 형태 HashMap과 동일함.
- 동기화된 메소드로 구성, 멀티 스레드 환경에서 안전하게 객체를 추가/삭제
- 스택(Stack)
- LIFO 자료구조로 구현
- 스택에서 사용하는 메소드
- push(값) : 값을 스택에 넣음.
- peek() : 스택의 맨 위 객체를 가져옴. 스택에서 삭제X
- pop() : 스택의 맨 위 객체를 가져옴. 스택에서 삭제O
- Queue
- FIFO 자료구조로 구현
- 큐에서 사용하는 메소드
- offer(객체) : 주어진 객체를 넣음
- peek() : 객체 하나를 가져옴. 큐에서 삭제X
- poll() : 객체 하나를 가져옴. 큐에서 삭제O
입출력 스트림
- 입출력 스트림 종류
- 바이트 기반 스트림
- 그림, 멀티미디어 등의 바이너리 데이터를 읽고 출력할 때 사용
- InputStream과 OutputStream은 바이트 기반 최상위 입출력 스트림
- 하위클래스들은 XXXInputStream/XXXOutputStream 형태
- 문자 기반 스트림
- 문자 데이터를 읽고 출력할 때 사용
- Reader와 Writer는 문자 기반 최상위 입출력 스트림
- 하위클래스들은 XXXReader/XXXWriter 형태
- OutputStream
- 모든 바이트 기반 출력 스트림 클래스에게 상속
- 바이트 기반 출력 스트림의 기본 메소드
- write(int b) : 주어지는 int에서 끝 1byte만 출력 스트림으로 보냄
- write(byte[] b) : 매개값으로 주어진 배열b의 모든 바이트 출력
- write(byte[] b, int off, int len) : b[off]부터 len개까지 바이트를 출력
- flush() : 출력 버퍼에 잔류하는 모든 바이트 출력
- close() : 출력 스트림을 닫음
- InputStream
- 모든 바이트 기반 입력 스트림 클래스에게 상속
- 바이트 기반 입력 스트림 기본 메소드
- read() : 입력 스트림으로부터 1byte를 읽고 int타입으로 반환
- read(byte[] b) : 읽은 바이트를 주어진 배열에 저장, 읽은 바이트 수를 반환
- read(byte[] b, int off, int len) : len개의 바이트를 읽고 b[off]부터 len개까지 저장, 읽은 바이트수 반환
- close() : 입력 스트림을 닫음
- Write
- 모든 문자 기반 출력 스트림 클래스에게 상속
- 문자 출력 스트림 기본 메소드
- write(int c) : 한 문자만 보냄
- write(char[] cbuf) : 배열의 모든 문자를 보냄
- write(char[] cbuf, int off, int len) : cbuf[off]부터 len개까지 문자를 보냄.
- write(String str) : 문자열을 보냄
- write(String str, int off, int len) : 문자열에서 off 순번부터 len개까지 문자를 보냄
- flush() : 버퍼에 잔류하는 모든 문자를 출력
- close() : 출력 스트림을 닫음
- Reader
- 모든 문자 기반 입력 스트림 클래스에게 상속
- 문자 입력 스트림 기본 메소드
- read() : 1개의 문자를 읽고 반환
- read(char[] cbuf) : 읽은 문자들을 주어진 문자 배열에 저장하고 읽은 문자수를 반환
- read(char[] cbuf, int off, int len) : len개의 문자를 읽고 주어진 문자배열에서 cbuf[off]부터 len개까지 저장, 읽은 문자수 반환
- close() : 입력 스트림을 닫음
- 보조 스트림
- 다른 스트림과 연결이 되어 여러가지 편리한 기능을 제공하는 스트림
- 형태
보조스트림 변수 = new 보조스트림(연결스트림)
- 문자 변환 보조 스트림
- outputStreamWriter : 문자 출력 스트림인 Writer로 변환하는 보조 스트림
- InputStreamReader : 문자 출력 스트림인 Reader로 변환하는 보조 스트림
- BufferedOutputStream : 바이트 기반 출력 스트림과 연결되어 버퍼를 제공
- BufferedWriter : 문자 기반 출력 스트림과 연결되어 버퍼를 제공
- BufferedOutputSteam과 BufferedWriter는 프로그램에서 전송한 데이터를 내부버퍼에 쌓고, 꽉차면 버퍼의 모든 데이터를 한번에 보냄.
- BufferedInputStream : 바이트 기반 입력 스트림과 연결되어 버퍼를 제공
- BufferedReader : 문자 기반 입력 스트림과 연결되어 버퍼를 제공
- BufferedInputStream과 BufferedReader은 입력 소스에서 데이터를 미리 버퍼에 저장
- 프린터 보조 스트림
- PrintStream/PrintWriter는 print(), println() 메소드를 가지고 있는 보조 스트림
- 객체 입출력 보조 스트림
- ObjectOutputStream : 객체를 직렬화(객체를 바이트 배열로 만듬.)
- ObjectInputStream : 객체를 역직렬화(바이트 배열을 객체로 복원.)
- File 클래스
- 파일 및 폴더 정보를 제공해주는 역할
- File 클래스의 메소드
- exists() : 파일이나 폴더가 존재하는지 체크
- createNewFile() : 새로운 파일 생성
- mkdir() : 새로운 폴더를 생성
- mkdirs() : 경로상에 없는 모든 폴더를 생성
- delete() : 파일 또는 폴더를 삭제
- canExecute() : 실행할 수 있는 파일인지 체크
- canRead() : 읽을 수 있는 파일인지 체크
- canWrite() : 수정 및 저장할 수 있는 파일인지 체크
- getName() : 파일 이름 반환
- getParent() : 부모 폴더 반환
- getParentFile() : 부모 폴더를 File객체로 생성 후 반환
- getPath() : 전체 경로 반환
- isDirectory() : 폴더인지 체크
- isFile() : 파일인지 체크
- isHidden() : 숨김 파일인지 체크
- lastModified() : 마지막 수정 날짜 및 시간 반환
- length() : 파일 크기 반환
- list() : 폴더에 포함된 파일 및 서브 폴더 목록 전부 String 배열로 반환
- list(FilenameFilter filter) : 폴더에 포함된 파일 및 서브 폴더 목록 중 필터에 맞는 것만 String 배열로 반환
- listFiles() : 폴더에 포함된 파일 및 서브 폴더 목록 전부 File 배열로 반환
- listFiles(FilenameFilter filter) : 폴더에 포함된 파일 및 서브 폴더 목록 중 필터에 맞는 것만 File 배열로 반환