com.eomcs.oop.ex04

com.eomcs.oop.ex04.Exam0111.java

바이트 배열을 가지고 String 인스턴스 초기화시키기
String(byte[]) 생성자를 호출하여 인스턴스 초기화

파일로부터 텍스트를 읽어들일 때, 네트워크로 텍스트가 넘어올 때
바이트 배열로 넘어옴
캐릭터 배열로 넘어오는 게 아님!
현재 지구상에 데이터를 처리는 기본 단위는 바이트
이미를 주고 받을 때도 바이트들의 배열을 주고 받는 거
음성조차 바이트들로 바뀜
카메라로 사진 찍을 때로 바이트들로 바꿔서 저장
텍스트든 뭐든간에 기본 단위가 바이트
다만 그 바이트를 좀 더 쉽게 다룰 수 있도록
short ← 2개의 바이트를 묶어서 마치 하나인 것처럼 다루고
int ← 4개의 바이트를 묶어서 마치 하나의 메모리처럼 다루고
long ← 8개의 바이트를 묶어서 마치 한 단위인 것처럼 다루는 것뿐이지
지구상에 존재하는 데이터는 기본으로 바이트
한 바이트는 8비트로 이루어져 있다
바이트를 묶어서 마치 그게 한 단위인 것처럼 다루는 것 뿐이지

영어 1 byte
EUC-KR : 한글 2 byte
UTF-8 : 한글 3 byte
Unicode(UTF-16) : 한글 2 byte

EUC-KR과 Unicode는 같은 2byte이지만
EUC-KR 2 byte와 유니코드의 2 byte는 규칙이 다르다

com.eomcs.oop.ex04.Exam0112.java

한글 문자 코드의 바이트 배열을 가지고 String 인스턴스 초기화시키기

byte[] bytes = {
    (byte)0xb0, (byte)0xa1, // 가 (EUC-KR 코드)
    (byte)0xb0, (byte)0xa2, // 각 (EUC-KR 코드)
    (byte)0xb6, (byte)0xca, // 똘 (EUC-KR 코드)
    (byte)0xb6, (byte)0xcb  // 똥 (EUC-KR 코드)
};

byte 배열에 있는 거 EUC-KR 규칙으로 작성한 거라고 알려줘야 됨

String s1 = new String(bytes, "EUC-KR");

두 번째 파라미터에 어떤 규칙에 따라 만들어졌다고 알려주기

-Dfile.encoding=UTF-8 옵션 주지 말고 두 번째 파라미터에 바이트 배열이 뭘로 되어 있는지 알려주기!

String(byte[] bytes) ← 3년 동안 이 생성자 쓰지 말기

String(byte[] bytes, String charsetName) ← 생성자 이걸로 쓰기

String : 문자열을 다루는 클래스
Integer : 정수를 다루는 클래스
클래스 이름에 무슨 역할을 하는지 나와 있음

java.util.Date : 날짜 데이터를 다루는 클래스

println()에 객체 주소를 넘겨주면 toString()을 호출해서
인스턴스에 있는 값을 문자열로 만들어서 리턴

KST : 한국 시간

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Date.html#constructor.summary

자바는 하위 버전 호환

단점 : 예전에 이미 버렸던 걸 아직까지 지금도 사용 가능
쓰지 말라고 경고만 할 뿐이지 동작이 안 되는 건 아님
쓰레기가 계속 쌓여가고 있음

장점 : JVM에 완벽하게 믿음이 있음
최신 버전 설치해도 하위버전을 완벽하게 실행함

시간을 안 알려주면 무조건 0시 0분 0초

유효한 생성자는 2개

1000L * 60 : 1분

com.eomcs.oop.ex04.Exam0130.java
java.util.Calendar 클래스의 생성자

Cannot instantiate the type Calendar

protected Calendar()

• protected : 같은 패키지에 있거나 내 자식만 사용 가능

• public : 모두 사용 가능

• 아무것도 안 붙임 : 같은 패키지만 사용 가능

• private : 나만 씀

https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Calendar.html

생성자가 아닌 static 메서드를 호출해서 인스턴스를 받는다.

인스턴스를 생성해주는 메서드는 보통 이름이
getOOO, createOOO, generateOOO

Calendar 사용법

Calendar.getInstance()

Calendar 객체(인스턴스)

Calendar cal = Calendar.getInstance()

get(int field)

cal.get(달력에서 꺼내고 싶은 값의 아이디)
값의 아이디는 숫자로 되어 있다.

cal.get(14) → 년 월 일 시:분:초:밀리초
밀리초 : 0 ~ 999

cal.get(1) → 년

상수값을 정해놓음
cal.get(Calendar.YEAR)
값의 아이디를 암기하기 힘들다. 그래서 스태틱 상수에 미리 그 번호를 저장해 두었다. 상수는 문자이기 때문에 이해하기 쉽다.

public static final int YEAR = 1;

값을 바꾸면 안 되는 경우 final 붙인다

데이터타입 변수명은 항상 붙어 있는다

modifier 성질을 바꾼다

public static final

System.out.println(c1.get(1)); // 2022
System.out.println(c2.get(Calendar.YEAR)); // 2022

Calendar 생성자가 protected로 막혀 있어서

com.eomcs.oop.ex04.Exam0210.java

String s1 = new String("Hello");

s1.compareTo(s2)
s1.contains("ll")
s3.getBytes("EUC-KR");
인스턴스 메서드. 인스턴스가 있어야 호출 가능.

두 개의 문자열을 비교했을 때
양수 : 인스턴스보다 앞쪽 순서
0 : 같음
음수 : 인스턴스보다 뒤쪽 순서

String.format()
String.join()
String.valueOf()

Immutable 객체와 String

String 클래스는 불변(immutable) 객체

처음 객체를 만들면 그 객체에 들어 있는 값을 변경할 수 없다.

새 문자열을 만든다.

System.out.println(System.identityHashCode(s1));

com.eomcs.oop.ex04.Exam0220.java

primitive type과 wrapper 클래스

int → java.lang.Integer
byte → java.lang.Byte
short → java.lang.Short
long → java.lang.Long
float → java.lang.Float
double → java.lang.Double
boolean → java.lang.Boolean
char → java.lang.Character

클래스는 다 대문자로 시작

int a = 10;
내부적으로 value라는 변수에 10을 저장
인스턴스 변수 value에 10을 저장하는 거

primitive type에 값을 다룰 수 있는 다양한 메서드를 추가해서 wrapper 클래스 만든 거

자바스크립트는 모든 게 객체

com.eomcs.oop.ex04.Exam0220.java

Interger.parseInt()
Float.parseFloat()
Boolean.parseBoolean()
parseOOO 클래스마다 있음
static 메서드

com.eomcs.oop.ex04.Exam0221.java
Integer 클래스: new Integer() vs Integer.valueOf()

이 메서드는 항상 -128에서 127(포함) 범위의 값을 캐시하고

Integer i1 = Integer.valueOf(127);
127까지만 true 나옴

com.eomcs.oop.ex04.Exam0240.java
java.sql.Date
2022-01-06 형식으로 나옴

com.eomcs.oop.ex04.Exam0250.java
상수 활용
스태틱 변수

113 ~ 250 정리

basic.ex02

문자열 다루는 거 하겠음

com.eomcs.basic.ex02.Exam0110.java
String - 문자열 객체 만들기

스트링 리터럴로

Method Area
명령문 (변수 선언문)

JVM Stack
로컬 변수

Heap
인스턴스 변수
value : char[]
배열이지만 일단은 문자열 통째로...

생성자 메서드 호출도 생략하겠음

s1에 들어 있는 주소랑 s2에 들어 있는 주소가 다르다.

com.eomcs.basic.ex02.Exam0111.java

String Pool에 String 인스턴스 생성
중복해서 안 만듦
JVM이 끝날 때까지 메모리에 유지된다.

java string constant pool 검색

/java-lang/bin/main/com/eomcs/basic/ex02/Exam0112.class

com.eomcs.basic.ex02.Exam0112.java

스트링 리터럴로 생성한 String 인스턴스를 두는 곳

하나는 Heap에 만들어지고 하나는 String Pool에 만들어진다.
주소가 다르므로 false

레퍼런스는 무조건 주소만 저장

String Pool에 이미 같은 문자열의 인스턴스가 있다면, 그 주소를 리턴한다.

리터럴로 만드는 경우와 new 명령으로 만드는 경우

intern() : 일정 구역에 억류하다

해당 문자열을 가진 String 객체를 String Pool에서 찾는다. 있으면 그 객체를 리턴한다. 없으면 새 객체를 만들고 리턴한다.

먼저 상수풀에 String 객체를 찾는다. 없으면 새로 만든다.

문자열 같은 경우에는 리터럴로 생성한다.

110 ~ 114 정리

com.eomcs.basic.ex02.Exam0120.java

equals() : 주소가 아니라 문자열이 같은지 비교

equalsIgnoreCase() : 대소문자 구분없이 문자열을 비교

122, 123 넘어가기

com.eomcs.basic.ex02.Exam0124.java

StringBuffer.equals() : 주소 비교

상속, 오버라이딩 배운 다음에 124번 마저 하겠음

com.eomcs.mylist.App.java

파일 확장자가 아니라 내장 변수

자바의 모든 클래스는 class 라는 내장 변수를 가지고 있다.
class 정보가 담겨 있다.

static Class class

타입이 Class

class 정보를 저장

App.class : App이라는 class 정보를 담고 있는 변수

com.eomcs.mylist.controller.ContactController.java

  ArrayList contactList;

  public ContactController() {
    contactList = new ArrayList();
    System.out.println("ContactController() 호출됨!");
  }

Spring Boot 실행 과정

90-MyList프로젝트1 / 41 페이지

SpringApplication.run(App.class, args); 실행 순서

① App 클래스가 소속된 패키지를 뒤진다.
@Component, @Controller, @Service, @Repository, @RestController 등의 애노테이션이 붙은 클래스를 찾아 인스턴스를 생성한다.
③ 생성한 인스턴스를 빈 컨테이너(Bean Container)에 보관한다.
  - Bean : 자바 객체를 가리키는 용어
  - Container : 객체를 생성하고 소멸까지 관리

Bean → Coffee  Bean
        Java  Object

Bean → Coffee Bean
   - Coffee = Java
   - Bean = Object
Container → 물건을 담는 공간
   물건 = 자바 객체
   + (생성 → 소멸) 관리
   객체의 life cycle(생명 주기)를 관리
@Controller@RestController가 붙은 클래스에서 @RequestMapping / @GetMapping / @PostMapping 관련 메서드를 분석하여 요청 처리 정보를 준비한다.
⑤ 요청이 들어오면 요청 처리 메서드(request handler)를 호출한다.

애노테이션이 안 붙은 클래스는 인스턴스 생성을 안 할까?
기본 생성자 만들기

  public Contact() {
    System.out.println("Contact() 호출됨!");
  }
  public Board() {
    System.out.println("Board() 호출됨!");
  }
  public Todo() {
    System.out.println("Todo() 호출됨!");
  }

애노테이션 안 붙인 클래스는 객체(인스턴스)가 안 만들어진다.

애노테이션을 붙여보자

애노테이션을 붙이니까 생성자가 호출되었다. 인스턴스를 생성했다.

근데 얘네들은 처음에 스프링부트를 실행할 때 자동으로 만들 이유가 없음
얘네들은 클라이언트 요청이 들어 왔을 때 만들어져야 됨
데이터를 저장하는 객체로서 데이터를 저장할 필요가 있을 때 만드는 거지 무조건 서버를 스타트하자마자 만들 이유가 없음

Controller는 스프링부트가 시작할 때 미리 만들어져 있어야지 클라이언트 요청이 들어오면 처리할 수 있음

애노테이션 다시 지우기

과연 Spring Bean Container에는 Controller만 들어 있을까?

Spring Boot의 Bean Container 내용물 확인하기

90-MyList프로젝트1 / 42 페이지

① 스프링 부트를 시작하게 되면
② 스프링 부트가 Tomcat Server를 띄운다.
Tomcat Server에서는 웹 서버와 서블릿 컨테이너가 들어 있다.
서블릿 컨테이너 : 서블릿 생성에서 소멸까지 관리
Servlet : 서버 애플리케이션의 작은 조각
웹 서버를 내부적으로는 웹 컨테이너라고 부를 때도 있다.
③ Spring Bean Container를 시작한다.
④ 스프링 부트 관련 객체 생성
com.eomcs.mylist 탐색 → 객체 생성
애노테이션이 붙은 클래스를 찾아서 인스턴스를 생성한다.
⑤ 애플리케이션 객체 생성
boardController, contactController, todoController
나머지는 다 스프링 부트 관련 객체들

객체가 생성되는 시점은 언제인가

스프링 부트가 만든다

DispatcherServlet이라는 Front Controller가 있다.

프론트쪽에 있는 제어자, 통제자
Front Controller
DispatcherServlet

① 웹 서버에 요청이 들어온다
예) /board/add
② 요청 전달
요청을 서블릿 컨테이너에 전달
③ 서블릿 컨테이너가 DispatcherServlet 실행
모든 요청은 DispatcherServlet이 받는다
Dispatcher : 요청을 배달한다. (요청 배달자)
Serv : Server Application
let : 작은 것을 뜻하는 접미사
Servlet : 서버 애플리케이션의 작은 조각
DispatcherServlet : 요청 배달을 하는 조각
④ 요청 처리기 요구
DispatcherServlet이 Spring Bean Container에 요청 처리기 요구
요청 처리기 : Page Controller
⑤ 요청 처리기 리턴
Spring Bean Container가 요청 처리기 리턴
예) BoardController 리턴
Page Controller : 특정 페이지 요청을 처리
⑥ 메서드 호출
DispatcherServlet이 request handler 호출
예) add() 호출
요청할 때 데이터가 넘어옴
⑦ 객체 생성 → 값 저장
DispatcherServlet이 Board 객체 생성 후 값 저장
⑧ 메서드 호출할 때 Board 객체를 파라미터에 넘겨준다.
⑨ 메서드 실행
BoardController가 add() 실행

인사관리시스템 ← 서버 애플리케이션
새 직원 등록, 퇴사, 직원 조회, 부서 조회, 부서 등록, 결재 등록, 결재 ← 서블릿 (서버의 작은 조각)

add() 메서드를 호출하는 DispatcherServlet이 Contact 객체를 생성해서 메서드를 호출할 때 파라미터로 넘겨준다.

클라이언트 요청이 들어올 때마다 그 요청을 받을 Contact 객체를 만들고 거기에 클라이언트가 보낸 요청 정보를 담은 다음에 ContactController에 add()를 호출할 때 파라미터로 넘겨준다.

전제 조건
스프링 부트를 시작할 때 Spring Bean Container에 Controller는 이미 존재한 상태여야 한다.

https://spring.io/guides/gs/spring-boot/

	@Bean
	public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
		return args -> {

			System.out.println("Let's inspect the beans provided by Spring Boot:");

			String[] beanNames = ctx.getBeanDefinitionNames();
			Arrays.sort(beanNames);
			for (String beanName : beanNames) {
				System.out.println(beanName);
			}

		};
	}

Bean Container에 146개의 객체가 들어 있다.

App.java 실행
main() 호출
SpringApplication.run() 실행
Tomcat Server를 띄운다
Tomcat Server 안에는 웹 서버와 서블릿 컨테이너가 있다.
Spring Bean Container 시작
mylist를 다 뒤져서
스프링 부트 관련 객체 생성
애플리케이션 객체 생성

그래서 최종적으로 Bean Container에 뭐가 들어 있는지 본 거임

실제로 Spring Bean Container는 창고 역할만 함
RequestMappingHandlerMapping 이라고 또 있음..

BoardController에 메서드가 많은데 어떻게 찾지?
@RequestMapping("/board/add") 이걸로 메서드 찾음
add() 메서드에 Board 객체를 달라고 정의되어 있음
메서드를 호출하기 전에 Board 객체를 먼저 생성한다.
클라이언트가 보낸 데이터를 Board 객체에 담는다.
그리고 그 객체 주소를 add() 메서드를 호출할 때 파라미터로 넘겨준다.
비로소 add()가 실행된다.

Controller 객체는 스프링 부트가 만든다.
Contact, Board, Todo 객체는 DispatcherServlet이 만든다.
메서드를 호출할 때 파라미터를 달라고 하니까 그때 만든다.

add() 메서드를 호출할 때 생성한다.

해당되는 메서드를 호출하는 그 시점에 파라미터가 객체면 그때 DispatcherServlet이 만든다

스프링 부트가 알아서 객체를 만든다.
클래스 위에 @로 표시를 하면 스프링 부트가 객체를 자동 생성

Contact, Board, Todo에는 @ 안 붙임

스프링 부트가 다 해줘서
클라이언트 요청을 처리할 Controller 클래스만 만들면 됨
클라이언트가 보낸 데이터를 저장할 데이터 타입만 정의하면 됨

Controller를 만들 때는 static 필드, static 메서드를 안 쓴다.
인스턴스 가지고 작업을 해야 돼서

App.java 실행하면 생성자가 호출됨
내가 호출한 게 아님
스프링 부트 run 하는 순간 App.class 설정된 대로 뒤진다
애노테이션 붙은 클래스 다 찾아서 딱 한 개 생성한다.
그 객체들의 주소를 스프링 부트는 갖고 있음
Controller 객체를 스프링 부트가 만든다

Book 클래스 만들기

public class Book {

왜 public을 붙이나
현재 패키지에서만 쓰는 게 아니라 다른 패키지에서도 써야 됨

Book 설계도에 따라서 메모리를 만들 건데 그 메모리에 뭘 담을 거냐
책 정보를 담을 거

게시글 참고해서 독서목록

1인용이 아닌 멀티유저로 바꾸는 순간 회원가입, 로그인, 로그아웃 기능이 들어가야 됨

백엔드 먼저 다 만들고 프론트엔드 만들기

0개의 댓글