객체 지향 프로그래밍 언어
특징
JVM
)을 설치하면 운영체제의 상관없이 작동(운영체제에 독립적)Primitive Type
)을 제외한 모든 요소들이 객체로 표현OOP
)의 특징들이 잘 적용된 언어클래스, 객체, 인스턴스
/* 클래스 */
public class Animal {
...
}
/* 객체와 인스턴스 */
public class Main {
public static void main(String[] args) {
Animal cat, dog; // '객체'
// 인스턴스화
cat = new Animal(); // cat은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
dog = new Animal(); // dog은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
}
}
클래스
: 세계객체
: 세계의 대상인스턴스
: 대상을 실체화Object-Oriented Programming
데이터를 객체로 취급하여 프로그램에 반영
절자 지향 프로그래밍과는 다르게 객체들의 상호작용을 통해 프로그램이 동작
장점
💖특징
1) 추상화
2) 캡슐화
3) 상속
4) 다형성
동작 방식이 다르고 이름이 같은 메서드를 호출
동일한 명령의 해석을 연결된 객체에 의존
오버라이딩: 부모 클래스의 메서드와 같은 이름, 매개변수를 갖고 내용은 다르도록 자식 클래스에서 메서드를 재정의하는 것.
public class Main {
public static void main(String[] args){
Child c = new Child();
c.print(20);
}
static class Parent {
int a = 10;
void print(int x){
System.out.println(this.a + x);
}
}
static class Child extends Parent {
int a = 10;
@Override
void print(int x){
System.out.println(x + x);
}
}
}
//40
오버로딩: 한 클래스 내에서 이름만 같고 매개변수의 타입과 수를 다르게 하여 메서드를 정의하는 것.
public class Main {
public static void main(String[] args){
A a = new A();
a.print(10);
a.print(10, 20);
}
static class A {
int a = 10;
void print(int x){
System.out.println(this.a + x);
}
void print(int x, int y){
System.out.println(this.a + x + y);
}
}
}
//20
//40
5) 동적 바인딩
Interface
추상 메서드
와 상수
만을 멤버로 갖는다.extends
는 하나의 클래스 상속, implements
는 다중 상속Abstract
공통점
new
연산자로 인스턴스 생성 불가능차이점
Abstract
는 일반 메서드 사용 가능, Interface
는 메서드 선언만 가능Interface
만이 다중상속 가능예제
public class Main {
public static void main(String[] args) {
String str = "str";
C c = new C();
System.out.println(c.getStrInterface(str));
System.out.println(c.getStrAbstract(str));
}
}
interface A {
String getStrInterface(String strA);
}
abstract class B {
String getStrAbstract(String strB){
return strB;
}
}
class C extends B implements A {
String c = "c";
@Override
public String getStrInterface(String strA) {
return c + strA;
}
@Override
String getStrAbstract(String strB) {
return super.getStrAbstract(strB);
}
}
//cstr
//str
C
클래스에서 A
인터페이스에 선언한 메서드를 정의하지 않으면 오류가 난다.B
는 정의하지 않아도 된다. 재정의하여 다른 내용으로 변경하고 싶을 때 메서드 오버라이딩(다형성)!==
equals()
클래스가 로딩될 때, 메모리 공간을 할당하는데 처음 설정된 메모리 공간이 변하지 않음을 의미
객체를 아무리 만들어도 해당 변수는 하나만 존재 (객체와 무관한 키워드)
🧨Static vs Instance
Static Method
메소드 내에서 인스턴스 변수를 사용하지 않는다.
객체를 생성하지 않고 호출
public class Main {
static int add(int x, int y) {
return x + y;
}
public static void main(String []args) {
System.out.println(add(1, 2));
}
}
Instance Method
객체 생성 후 사용 가능
class Pos {
int x;
int y;
public Pos(int x, int y) {
this.x = x;
this.y = y;
}
public int add(int x, int y){
return x + y;
}
}
public class Main {
public static void main(String[] args) {
Pos p = new Pos(1, 2);
System.out.println(p.add(p.x, p.y);
}
}
byte
, short
, int
, long
float
, double
char
boolean
int
→ Integer
char
→ Character
float
→ Float
등)public
: 접근 제한이 없다. (같은 프로젝트 내 어디서든 접근 가능)protected
: 같은 패키지 내, 다른 패키지에서 상속받아 자식 클래스에서 접근 가능defalut
: 같은 패키지 내 접근 가능private
: 같은 클래스 내 접근 가능synchronized
Thread
간 동기화를 통해 data
의 thread-safe
보존Runnable
: Java의 Thread 구현 인터페이스
run()
💥동기화하지 않은 예제
public class Test {
public static void main(String[] args) throws InterruptedException {
Task task = new Task();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}
class Task implements Runnable {
Account acc = new Account();
@Override
public void run() {
while (acc.current > 0) {
// 100, 200, 300 중의 한 값을 임의로 선택해서 출금(withDraw)한다.
int money = (int) (Math.random() * 3 + 1) * 100;
acc.withDraw(money);
}
}
}
class Account {
int current = 1_000;
public void withDraw(int money) {
if (current >= money) {
try {
Thread thread = Thread.currentThread();
System.out.println(thread.getName() + "의 출금 금액 ->> " + money);
Thread.sleep(1000);
current -= money;
System.out.println(thread.getName() + "의 현재 금액: " + current);
} catch (Exception e) {
}
}
}
}
t2의 출금 금액 ->> 300
t1의 출금 금액 ->> 300
t1의 현재 금액: 700
t1의 출금 금액 ->> 100
t2의 현재 금액: 400
t2의 출금 금액 ->> 100
t2의 현재 금액: 300
t2의 출금 금액 ->> 200
t1의 현재 금액: 200
t1의 출금 금액 ->> 200
t1의 현재 금액: 0
t2의 현재 금액: -200
💖동기화 예제
class Account {
int current = 1_000;
public synchronized void withDraw(int money) { //변경
/.../
}
}
t1의 출금 금액 ->> 300
t1의 현재 금액: 700
t2의 출금 금액 ->> 200
t2의 현재 금액: 500
t1의 출금 금액 ->> 200
t1의 현재 금액: 300
t2의 출금 금액 ->> 300
t2의 현재 금액: 0
네 가지 유형의 synchronized
1) 인스턴스 메소드 동기화
public synchronized void add(int num){
this.count += num;
}
2) Static 메소드 동기화
public static synchronized void add(int num){
this.count += num;
}
3-1) 인스턴스 메소드 안의 동기화 블록
public void add(int num){
synchronized(this){
this.count += num;
}
}
3-2) 두 개의 동기화된 블록
public class MyClass {
public synchronized void log1(String msg1, String msg2){
log.writeln(msg1);
log.writeln(msg2);
}
public void log2(String msg1, String msg2){
synchronized(this){
log.writeln(msg1);
log.writeln(msg2);
}
}
}
log2()
에 this
대신 다른 객체를 전달한다면 한 시점에 각 메서드 실행 가능4) Static 메소드 안의 동기화 블록
public class MyClass {
public static synchronized void log1(String msg1, String msg2){
log.writeln(msg1);
log.writeln(msg2);
}
public static void log2(String msg1, String msg2){
synchronized(MyClass.class){
log.writeln(msg1);
log.writeln(msg2);
}
}
}
자바 직렬화 (Serializaion)
사용 이유
Value Type
데이터로 변환해준다. 즉, 데이터를 저장, 통신전에 '데이터 직렬화(Serialization)' 작업이 필요🧨정의
byte
형태로 변환byte
형태를 객체로 변환특징
❗Object
객체는 최상위 객체기 때문에 직렬화가 불가능
부모 클래스에서 직렬화를 상속받으면 자식 클래스도 자동 직렬화
public class SuperUserInfo implements Serializable {
String name;
String password;
}
public class UserInfo extends SuperUserInfo {
int age;
}
다만, 아래와 같이 부모 클래스가 직렬화를 구현하지 않는다면 부모 클래스의 데이터(name
, password
)는 직렬화 대상에서 제외된다.
public class SuperUserInfo {
String name;
String password;
}
public class UserInfo extends SuperUserInfo implements Serializable {
int age;
}
transient
transient
가 선언된 데이터(변수)는 Serializable
대상에서 제외된다.volatile
JAVA 변수를 Main Memory에 저장(특히, 읽거나 쓸 때)
변수를 읽어들일 때마다, CPU cache가 아닌 M.M에서 읽어들인다.
🧨사용 이유
Thread
가 변수를 읽어올 때, 각각 cache
에 담긴 값이 다르기 때문에 변수값 불일치가 발생하는데 이를 해결하기 위함Thread
만 read & write
하고 나머지 Thread
는 read
하는 상황에서 최신의 값을 보장write
하는 경우에는 synchronized
를 통해 동기화하여 원자성을 보장JVM
+ Library
(자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일도 포함)JRE
+ 개발 툴
클래스 로더 시스템
메모리
1) 메소드 영역 : 클래스 레벨의 정보(클래스 이름, 부모 클래스 이름, 메소드, 변수) 저장. 공유 자원.
아무것도 상속받지 않은 클래스 같이 보이더라도 상위 클래스가 있다.
package me.jinmin;
public class App {
public static void main(String[] args) {
System.out.println(App.class.getSuperclass());
}
}
print:
class java.lang.Object
2) 힙 영역 : 객체(instance)를 저장. 공유 자원.
3) 쓰레드 영역
스택 영역 : 쓰레드마다 런타임 스택을 형성하고 그 안에 스택 프레임(=메소드 콜)을 쌓는다.
PC(Program Counter) register : 쓰레드마다 현재 실행할 스택 프레임을 가리키는 포인터
네이티브 메소드 스택 : https://javapapers.com/core-java/java-jvm-run-time-data-areas/#ProgramCounter_PC
Register
네이티브 메소드❓ : 메소드에 네이티브 키워드가 붙어있고 구현을 Java가 아닌 C, C++로 한 것.
@HotSpotIntrinsicCandidate
public static native Thread currentThread();
실행 엔진
네이티브 메소드 인터페이스 (JNI)
네이티브 메소드 라이브러리
로딩, 링크, 초기화 순
로딩
클래스 로더가 .class
파일을 읽고 내용에 따라 적절한 바이너리 데이터를 만들고 메소드
영역에 저장
메소드 영역에 저장하는 데이터
로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성해서 힙
영역에 저장.
package me.jinmin;
public class App {
public static void main(String[] args) {
Class<App> appClass; //로딩이 끝나면 만들어지는 요거.!!!
}
}
링크
.class
가 유효한지 검증초기화
❤클래스 로더는 계층 구조, 기본적인 3개의 클래스 로더로 이루어져 있다.
Bootstrap 클래스 로더 : JAVA_HOME\lib
에 있는 코어 자바 API 제공. 최상위 우선순위
Platform 클래스 로더 : JAVA_HOME\lib\ext
폴더 또는 java.ext.dirs
시스템 변수에 해당하는 클래스를 읽음.
Application 클래스 로더 : 애플리케이션 클래스 경로(-classpath
옵션 or java.class.path
환경 변수의 값에 해당하는 위치)에서 클래스를 읽음.
package me.jinmin;
public class App {
public static void main( String[] args ) {
ClassLoader classLoader = App.class.getClassLoader();
System.out.println(classLoader);
System.out.println(classLoader.getParent());
System.out.println(classLoader.getParent().getParent());
}
}
print:
jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
jdk.internal.loader.ClassLoaders$PlatformClassLoader@43a25848
null //native여서 참조 불가
Stack
Queue
인터넷을 통해 서버, 스토리지, 소프트 웨어 등 필요한 IT 자원을 받아 사용하는 것
서비스 형식
IaaS (Infrastructure as a Service) : IT 인프라(서버, 데이터 스토리지, 데이터베이스, 네트워크, 운영체제 등) 제공
PaaS (Platform as a Service) : 소프트웨어 애플리케이션을 위한 환경 제공 (웹 앱, 모바일 앱 등)
서버리스 : PaaS, 앱 기능 빌드에 초점, 특정 함수나 트리거가 발생할 때만 리소스 활용
SaaS (Software as a Service) : 모든 인프라와 소프트웨어 제공
주요 업체
Servlet
: Container가 이해할 수 있도록 구성된 순수 자바 코드 (Html in JAVA)JSP
(Java Server Page) : html 기반에 자바 코드를 블록화하여 삽입 (JAVA in Html)MVC 1
자바 코드
가 함께 사용html
과 자바 코드
가 함께 사용되어 복잡하고 유지보수가 어려움MVC 2
이름
과 값
이 결합된 스트링 형태로 전달GET
은 주로 웹 브라우저 → 웹 서버 데이터 요청POST
는 웹 브라우저 → 웹 서버 데이터 전달GET
은 데이터가 인코딩되어 URL에 노출 → 보안 낮음POST
는 데이터 노출 X → 보안 높음GET
은 255개의 문자를 초과하면 안된다.POST
는 많은 데이터 전달 가능, 제한 없다.HTTP 프로토콜
은 연결 지향적이지 않다. 새로운 페이지를 요청할 때마다 새로운 접속이 이루어지고 전 페이지와 현 페이지의 관계가 지속되지 않는다. 따라서 웹페이지에 방문자가 머무르고 있을 때, 방문자의 상태를 지속시키기 위해 Session
or Coookie
를 사용로그인
시도Secret Key
를 통해 Access Token
발급Authorization header
에 Access Token을 담아 요청JWT signature
를 체크하여 인증된 사용자 정보를 확인 후 원하는 데이터 반환JDBC
(Java Data Base Connection) : JAVA를 통해 DB에 접근하도록 하는 프로그래밍성질 (ACID)
읽기 이상 현상
격리 수준 (아래로 갈수록, 일관성은 좋다, 성능은 떨어진다.)
💖 격리 수준에 따른 이상 현상
Model
View
Controller
클래스 프레임
과 인터페이스 프레임
의 집합트랜잭션
이나 로깅
, 보안
과 같이 여러 모듈에서 공통적으로 사용하는 기능을 분리하여 관리ORM (Object-Relational Mapping)
JPA (Java Persistence API)
동작
애플리케이션과 JDBC 사이에서 동작 (조회, 저장 등)
🧨사용 이유
CRUD