6장 - 모듈과 패키지 개념, 자바 기본 패키지
패키지 - directory (중복 파일명 대비)
서로 관련있는 class, interface의 컴파일 된 class 파일 하나로 묶음
// 개발자 A - UI
Tools.class
// 개발자 B - FileIO
Tools.class
// 각각 다른 package로 - 하나의 package는 관련 class파일의 directory
Project.FileIO.Tools.class
Project.UI.Tools.class
jmods 디렉토리 안에 module 파일 존재 - zip 파일
// module - package 모음 (JDK 9)
// package - 관련 class 파일 directory
java.base // module - java.base 모듈 안에 util 포함
java.util // package
java.util.Scanner // scanner class
// package 사용 - import
// import 사용 X - directory 직접 작성
public class ImportExample {
public class void main(String[] args) {
java.util.Scanner scanner = new java.util.Scanner(System.in);
System.out.println(scanner.next();
}
}
// import 사용 O
import java.util.Scanner; // scanner class만 import
import java.util.*; // util package 내 모든 class 사용
public class ImportExample {
public class void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println(scanner.next());
}
}
// package 선언
package UI;
public class Tools { ... } // UI.Tools.class
// 다른 package에서 class 호출 사용
package Graphic;
import UI.Tools; // Tools class 경로명
public class Line {
public void draw() {
Tools t = new Tools(); // UI의 Tools class
}
}
default package - 현재 directory (package 따로 선언 X)
package 특징
1. 계층구조 (JDK - jmods > util, lib 등 (package)
2. 접근 제한
private // 동일 class 내 멤버만
default // 동일 package 내
protected // 동일 package 내 class & 자식 class
public // 모든 package에서 접근 가능
3. 동일한 이름 class, interface 사용 가능
UI.Tools.class
FileIO.Tools.class
4. 높은 재사용성
모듈 - 패키지, 이미지 등의 리소스 담은 container
Java 9에 처음 도입 / 모듈 파일 (.jmod)로 저장
JDK > jmods 디렉토리 > 모든 module
// java.base 모듈 - java.base.jmod 파일
jmod extract "{주소}" // java.base 모듈이 현재 디렉토리에 풀림
JRE - 자바 실행 환경 (java runtime environment)
= JVM, Java API 클래스 등
// Java 모듈화의 목적
1. component를 필요에 따라 조립, 사용하기 위함
2. 시스템의 불필요한 부담 감소 (필요 없는 모듈 load X)
JDK에서 제공하는 패키지 - java.lang은 자동 import

JDK 설치 > module > package - 기본 클래스 = Java API
```java
System.out.println(); // System - java.lang.System class
// Java API
// javadoc으로 보는 화면 - JDK 클래스의 method 확인
// 주요 패키지
// java.lang - 자동 import 됨
java.lang // - string, math, IO 등의 기본 class, interface
java.util // 날짜, 시간, 해시맵 등
java.io // 입출력 class, inteface
java.awt // Java GUI
javax.swing // GUI swing package
```
Object class (최상위 class)
Object - java.lang에 속한 class (모든 class에 강제 상속)
// Object class 주요 method
// 모든 객체에 있어야 할 method 포함
boolean equals(Object obj) // obj 객체, 현재 객체 비교, 같으면 true
Class getClass() // 현 객체 runtime class return
int hashCode() // hashcode 값 return
String toString() // 문자열 표현 return
void notify() // 대기하고 있는 thread 1개 깨움
void notifyAll() // 대기 중인 모든 thread 깨움
void wait() // 다른 thread 깨울 때까지 현재 thread 무한 대기
// getClass(), hashCode(), toString() method 활용
class Point{
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class ObjectPropertyEx {
public static void print(Object obj) {
System.out.println(obj.getClass().getName()); // class 타입
System.out.println(obj.hashCode()); // hashcode 값
System.out.println(obj.toString()); // 문자열로 출력
System.out.println(obj); // 객체 출력
}
public static void main(String[] args) {
Point p = new Point(2, 3);
print(p);
}
}
toString()
// toString() 자세히 - Object class의 method
public String toString() {
// Point@15db9742 출력
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 자동 toString() 호출
Point p = new Point(2, 3);
System.out.println(p); // p = p.toString() 자동 변환
String s = p + "점"; // p.toString() + "점" 자동 변환
// toString() 새로 작성 - 반드시 public
class Point {
private int x, y;
public Point(int x, iny y) {
this.x = x;
this.y = y;
}
public String toString() { // 반드시 public으로 override
return "Point (" + x + ", " + y + ")";
}
}
public class ToStringEx {
public static void main(String[] args) {
Point p = new Point(2, 3);
System.out.println(p.toString()); // "Point (2, 3)" 출력
System.out.println(p); // 위와 동일 (p.toString() 자동변환)
System.out.println(p + "입니다."); // p.toString() 자동변환
}
}
equals(Object obj) - obj와 this(자기 자신) reference ( == ) 비교
→ 내용을 비교하진 않음 / String class의 equals() - 두 문자열 동일 ?

// 기본 타입 값 비교 (a == b)
Point a = new Point(2, 3);
Point b = new Point(2, 3); // a, b는 서로 다른 객체
Point c = a; // a, c 같은 객체 가리킴
if (a == b) // false
System.out.println("a == b");
if (a == c) // true
System.out.println("a == c"); // "a == c" 출력
// 객체 비교 (a.equals(b))
class Point {
private int x, y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object obj) {
Point p = (Point)obj; // downcasting (Object -> Point)
if (x == p.x && y == p.y)
return true;
return false;
}
}
public class EqualEx {
public static void main(String[] args) {
Point a = new Point(2, 3);
Point b = new Point(2, 3);
Point c = new Point(3, 4);
if (a == b) // a, b 다른 객체
System.out.println("a == b");
if (a.equals(b)) // true
System.out.println("a is equal to b");
if (a.equals(c)) // a, c 다른 객체
System.out.println("a is equal to c");
}
}
Wrapper class - 기본 타입을 객체로 (java.lang)
wrapper 이란 이름의 class는 존재 X (java.lang에서 제공)
// 좌 : 기본 타입, 우 : 객체 타입
byte -> Byte // Wrapper class Byte
short -> Short
int -> Int
long -> Long
char -> Character // char은 풀네임으로
float -> Float
double -> Double
boolean -> Boolean
기본 타입 → 문자열 : toString()
문자열 → 기본 타입 : parseInt, parseDouble, parseBoolean 등
// Wrapper class 활용
static int bitCount(int i) // 정수 i 2진수에서 1 개수
float floatValue() // float 타입으로 return
int intValue()
long longValue()
short shortValue()
static int parseInt(String s) // 문자열 s -> 정수 return
static int parseInt(String s, int radix) // radix 진법으로 return
static String toBinaryString(int i) // 2진수 문자열
static String toHexString(int i) // 16진수
static String toOctalString(int i) // 8진수
static String toString(int i) // 문자열 return
static Integer valueOf(int i) // Integer 객체 return
static Integer valueOf(String s) // 문자열 s -> 정수 -> Integer 객체
// 기본 타입 알아내기 (valueOf, __Value)
Integer i = Integer.valueOf(10); // 정수 10을 객체 타입으로
int ii = i.intValue(); // 객체 i의 값 -> 정수로 (ii = 10)
Character c = Character.valueOf('c'); // 객체 타입
char cc = c.charValue(); // cc = 'c'
Double d = Double.valueOf(3.14);
double dd = d.doubleValue(); // dd = 3.14
Boolean b = Boolean.valueOf(true);
boolean bb = b.boolValue(); // bb = true
// 문자열 -> 기본 타입 (parse)
int i = Integer.parseInt("123"); // "123" -> 123, i = 123
boolean b = Boolean.parseBoolean("true");
double d = Double.parseDouble("3.14");
// 기본 타입 -> 문자열 (toString)
String s1 = Integer.toString(10);
String s2 = Integer.toHexString(10);
String s3 = Double.toString(3.14);
String s4 = Character.toString('a');
String s5 = Boolean.toString(true);
boxing & unboxing → 자동이다!!
// boxing : 기본 타입 -> 객체
// unboxing : 객체 -> 기본 타입
Integer ten = Integer.valueOf(10); // 10을 객체로 생성
int n = ten.intValue(); // n = 10
// boxing, unboxing은 자동
Integer ten = 10; // Integer.valueOf(10)으로 안해도 됨
int n = ten; // ten.intValue() 안해도 됨
public class AutoBoxingUnBoxingEx {
public static void main(String[] args) {
int n = 10;
Integer intObject = n; // 자동 boxing
System.out.println("intObject = " + intObject); // toString 자동 수행
// unboxing 아님 (unboxing : 객체 -> 기본 타입)
int m = intObject + 10; // 자동 unboxing (객체 -> 기본)
System.out.println("m = " + m); // m = 20
}
}
String class (java.lang)
객체 생성 방법 - 리터럴 사용 (JVM이 관리) / 생성자 이용 (Heap 메모리)
// String 리터럴로 String 객체 생성
String s1 = "abcd";
// String class 생성자 이용
char data[] = { 'a', 'b', 'c', 'd' };
String s2 = new String(data); // "abcd"
String s3 = new String("abcd"); // "abcd"
// String 객체 수정 불가
String s = new String("Hello"); // 객체
String t = s.concat("Java"); // 다른 객체 t 생성 (s는 여전히 "Hello")
// 문자열 관련 String method
// 비교 연산자 (compareTo, equals)
String java = "Java";
String cpp = "C++";
int result = java.compareTo(cpp); // result > 0 (사전 순)
// 연결 연산 ( + , concat)
System.out.print("abcd" + 123); // "abcd123"
"I love ".concat("Java."); // "I love Java."
// concat은 새로운 문자열 생성

// 공백 제거 (trim)
String a = " abcd ef"; // "abcd ef" : 문자열 앞뒤만 제거
// 문자열 내 문자 접근 (charAt)
String a = "class";
char c = a.charAt(2); // c = 'a'
StringBuffer class (java.lang)

// 문자열 변경 가능
// 객체 크기 따라 buffer 크기 가변적
StringBuffer sb = new StringBuffer("a");
sb.append(" pencil"); // buffer에 추가
sb.insert(2, "nice "); // offset (2) 위치에 str 추가
sb.replace(2, 6, "bad"); // (a, b, str) a~b-1을 str로 대체
sb.delete(0, 2); // 0~1 제거
sb.reverse(); // 역순 "licnep dab"
int n = sb.length; // n = 10
char c = sb.charAt(3); // c = n
sb.setLength(3); // buffer크기 3으로 줄이고 뒤에 다 버림
StringTokenizer class (java.util) - delimeter(구분문자) 다 붙여씀
// 문자열 분리를 위한 class - delimeter(구분문자) 다 붙여씀
String query = "name=kitae&addr=seoul&age=21";
// token : name=kitae, addr=seoul, age=21
StringTokenizer st1 = new StringTokenizer(query, "&");
// token : name, kitae, addr, seoul, age, 21
StringTokenizer st = new StringTokenizer(query, "&=");
// 주요 method
int countTokens() // token 개수 return
boolean hasMoreTokens() // 다음 token 존재 = true
String nextToken() // 다음 token return
import java.util.StringTokenizer;
public class StringTokenizerEx() {
public static void main(String[] args) {
StringTokenizer st = new StringTokenizer("홍길동/장화/홍련/콩쥐/팥쥐", "/");
while(st.hasMoreTokens())
System.out.println(st.nextToken());
} // 홍길동, 장화, 홍련, 콩쥐, 팥쥐 출력
}
Math class - (java.lang) : static method
// static method라 이름으로 바로 사용 가능
double d = Math.random();
double pi = Math.PI;
// 가장 많이 사용하는 Math method - random
double d = Math.random(); // 0.0 <= x < 1.0 랜덤 double
for (int i = 0; i < 10; i++) {
int n = (double)(Math.random() * 100 + 1); // 1 ~ 100 랜덤정수
System.out.println(n);
}
// Math class 대신 java.util.Random 사용해도 동일
import java.util.Random;
Random r = new Random();
int n = r.nextInt(); // (-2^31 ~ 2^31-1) 정수 발생
int m = r.nextInt(100); // 0~99 random
Calendar class - (java.util) : abstract class
MONTH, HOUR = 0~11임을 주의
cal.set(Calendar.JANUARY); → 0으로 설정
// Calendar는 추상 class -> 생성자 사용 불가
Calendar now = Calendar.getInstance(); // 객체 생성 (현재 정보)
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH) + 1; // 0~11이라 +1
int hour = now.get(Calendar.HOUR) + 1; // 0~11 + 1
int hour24 = now.get(Calendar.HOUR_OF_DAY); // 24시간제
// 날짜 직접 설정
Calendar firstDate = Calendar.getInstance(); // 객체 생성(현재 정보)
firstDate.clear(); // 현재 정보 지우기
firstDate.set(2024, 11, 25); // 2024-12-25, month + 1 주의
firstDate.set(Calendar.HOUR_OF_DAY, 20); // 저녁 8시
firstDate.set(Calendar.MINUTE, 30); // 30분으로 설정
// 지정 월 최대 일 수 확인 (2024-2월 최대 일 수)
import java.util.Calendar;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2024);
cal.set(Calendar.MONTH, 1); // 2월
int maxDay = cal.getAcutalMaximum(Calendar.DAY_OF_MONTH); // 29일
// 날짜 지정 -> 요일 알아내기
import java.util.Calendar;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2024);
cal.set(Calendar.MONTH, 1); // 2월
cal.set(Calendar.DAY_OF_MONTH, 5); // 2024-2-5 지정
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK); // 2024-2-5의 요일
// dayOfWeek = Calendar.MONDAY
// 날짜 지정 문제점
cal.set(Calendar.YEAR, 2024);
cal.set(Calendar.JANUARY); // 0으로 설정됨
// 해결법 - java.time.LocalDate 사용
import java.time.LocalDate;
LocalDate date = LocalDate.of(2024, 1, 15); // 2024-1-15 설정