API 도큐먼트
자바 표준 모듈에서 제공하는 라이브러리는 방대하기 때문에 쉽게 찾아서 사용할 수 있도록 도와주는 API 도큐먼트가 있다. 라이브러리가 클래스와 인터페이스의 집합이라면 API 도큐먼트는 이를 사용하기 위한 방법을 기술한 것이다.
벨로그 왜 나만 억까해?
java.base 모듈
java.base는 모든 모듈이 의존하는 기본 모듈로, 모듈 중 유일하게 requires하지 않아도 사용할 수 있다. 이 모듈에 포함되어 있는 패키지는 대부분의 자바 프로그램에서 많이 사용하는 것들이다. 아래는 java.base 모듈에 포함된 주요 패키지와 용도를 설명한 표이다.
![](https://velog.velcdn.com/images/namsm17/post/b94d4d11-dc28-41d5-a0db-d3180928b245/image.jpeg)
Object 클래스
클래스 선언할 때 extends 키워드로 다른 클래스를 상속하지 않으면 암시적으로 java.lang.Object 클래스를 상속하게 된다. 따라서 자바의 모든 클래스는 Object의 자식이거나 자손 클래스이다.
메소드 | 용도 |
---|
boolean equals(Object ob) | 객체의 번지를 비교하고 결과를 리턴 |
int hashCode() | 객체의 해시코드를 리턴 |
String toString() | 객체 문자 정보를 리턴 |
객체 동등 비교
Object의 equals() 메소드는 객체의 번지를 비교 후 boolean 값을 리턴한다.
public boolean equals(Object obj)
equals() 메소드의 매개변수 타입이 Object이므로 자동 타입 변환에 의해 모든 객체가 매개값으로 대입될 수 있다. equals() 메소드는 비교 연산자인 ==과 동일한 결과를 리턴한다. 두 객체가 동일한 객체라면 true를 아니라면 false를 리턴한다. 일반적으로 Object의 equals() 메소드는 재정의해서 동등 비교용으로 사용된다. 동등 비교란 객체가 비록 달라도 내부의 데이터가 같은지를 비교하는 것을 말한다.
public class Member {
public String id;
public Member(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Member target) {
if(id.equals(target.id)){
return true;
}
}
return false;
}
}
public class MemberExample {
public static void main(String[] args) {
Member obj1 = new Member("blue");
Member obj2 = new Member("blue");
Member obj3 = new Member("red");
if(obj1.equals(obj2)) {
System.out.println("obj1과 obj2는 동등합니다.");
}else {
System.out.println("obj1과 obj2는 동등하지 않습니다.");
}
if(obj1.equals(obj3)) {
System.out.println("obj1과 obj3은 동등합니다.");
}else {
System.out.println("obj1과 obj3은 동등하지 않습니다.");
}
}
}
객체 해시코드
객체 해시코드란 객체를 식별하는 정수를 말한다. Object의 hashCode() 메소드는 객체의 메모리 번지를 이용해서 해시코드를 생성하기 때문에 객체마다 다른 정수값을 리턴한다. hashCode() 메소드의 용도는 equals() 메소드와 비슷한데, 두 객체가 동등한지를 비교할 때 주로 사용한다.
public int hashCode()
equals() 메소드와 마찬가지로 hashCode() 메소드 역시 객체의 데이터를 기준으로 재정의해서 새로운 정수값을 리턴하도록 하는것이 일반적이다. 객체가 다르다 할지라도 내부 데이터가 동일하다면 같은 정수값을 리턴하기 위해서이다.
객체 문자 정보
Object의 toString() 메소드는 객체의 문자 정보를 리턴한다. 객체의 문자 정보란 객체를 문자열로 표현한 값을 말한다. 기본적으로 Object의 toString() 메소드는 '클래스명@16진수해시코드'로 구성된 문자열을 리턴한다.
객체의 문자 정보가 중요한 경우에는 Object의 toString() 메소드를 재정의해서 간결하고 유익한 정보를 리턴하도록 해야한다.
레코드 선언
데이터 전달을 위한 Dto 작성시 중복 코드 삭제를 위해 레코드를 도입되었다.
class 키워드 대신 record로 대체하며 클래스 이름 뒤에는 괄호를 작성해서 저장할 데이터의 종류를 변수로 선언한다.
public record Member(String id, String name, int age) {
}
public class RecordExmaple {
public static void main(String[] args) {
Member m = new Member("Winter", "눈송이" , 25);
System.out.println(m.id());
System.out.println(m.name());
System.out.println(m.age());
System.out.println(m.toString());
System.out.println();
Member m1 = new Member("winter", "눈송이", 25);
Member m2 = new Member("winter", "눈송이", 25);
System.out.println("m1.hashCode() : " + m1.hashCode());
System.out.println("m2.hashCode() : " + m1.hashCode());
System.out.println("m1.equals(m2): " + m1.equals(m2));
}
}
롬복 사용하기
롬복은 JDK에 포함된 표준 라이브러리는 아니지만 개발자들이 자주 쓰는 자동 코드 생성 라이브러리이다. 롬북은 레코드와 마찬가지로 DTO 클래스를 작성할 때 Getter, Setter, hashCode(), equals(), toString() 메소드를 자동 생성하기 때문에 작성할 코드의 양을 줄여준다. 레코드와 차이점은 필드가 final이 아니며, 값을 읽는 Getter는 getXxx 값을 변경하는 Setter는 SetXxx로 생성된다는 것이다.
@Data 외에도 아래와 같은 어노테이션을 사용 가능하다.
![](https://velog.velcdn.com/images/namsm17/post/5621666f-d1f5-4840-ae93-961795b3b0e1/image.jpeg)
System 클래스
java.lang 패키지에 속하는 System 클래스를 이용하면 운영체제의 일부 기능을 이용할 수 있다. System 클래스의 정적 필드와 메소드를 이용하면 프로그램 종료, 키보드 입력, 콘솔 출력 등이 가능하다.
![](https://velog.velcdn.com/images/namsm17/post/fa8c44fe-554a-4d17-a0ca-6ed276356b73/image.jpeg)
콘솔 출력
out 필드를 이용하면 콘솔에 원하는 문자열을 출력할 수 있다. err필드도 out필드와 동일한데, 차이점은 콘솔 종류에 따라 에러 내용이 빨간색으로 출력된다는 것이다.
인텔리제이는 빨간색으로 안나오던데
키보드 입력
자바는 키보드로부터 입력된 키를 읽기 위해 System 클래스에서 in 필드를 제공한다.
int keyCode = System.in.read();
키코드는 아래와 같다.(아스키)![](https://velog.velcdn.com/images/namsm17/post/8e8afa3d-6b19-4c64-95ab-7795e94afbca/image.jpeg)
public class IntExample {
public static void main(String[] args) throws Exception {
int speed = 0;
int keyCode = 0;
while (true) {
if (keyCode != 13 && keyCode != 10) {
if (keyCode == 49) {
speed++;
} else if (keyCode == 50) {
speed--;
} else if (keyCode == 51) {
break;
}
System.out.println("----------------------------");
System.out.println("1. 증속 | 2. 감속 | 3. 중지");
System.out.println("----------------------------");
System.out.println("현재 속도 = " + speed);
System.out.println("선택 : ");
}
keyCode = System.in.read();
}
System.out.println("프로그램 종료");
}
}
문자열 클래스
클래스 | 설명 |
---|
String | 문자열을 저장하고 조작할 때 사용 |
StringBuilder | 효율적인 문자열 조작 기능이 필요할 때 사용 |
StringTokenizer | 구분자로 연결된 문자열을 분리할 때 사용 |
String 클래스
문자열 리터럴은 자동으로 String객체로 생성되지만 String 클래스의 다양한 생성자를 이용해서 직접 객체를 생성할 수 도 있다. 프로그램을 개발하다 보면 byte 배열을 문자열로 변환하는 경우가 종종있다.
StringBuilder 클래스
String은 내부 문자열을 수정할 수 없다. 다음 코드를 보면 다른 문자열을 결합해서 내부 문자열을 변경하는 것 처럼 보이지만 사실 'ABCDEF' 라는 새로운 String 객체를 생성하는 것이다. 그리고 data변수는 새로 생성된 String 객체를 참조하게 된다.
String처럼 새로운 객체를 만들지 않고도 문자열을 조작할 수 있다. toString()을 제외한 메소드는 StringBuilder를 다시 리턴하기 때문에 연이어서 다른 메소드를 호출할 수 있는 메소드 체이닝패턴을 사용할 수 있다.
StringTokenizer 클래스
문자열이 구분자로 연결되어 있을 경우, 구분자를 기준으로 문자열을 분리하려면 String의 split()메소드를 이용하거나 StringTokenizer 클래스를 이용가능하다. split은 정규 표현식으로 구분하고, StringTokenizer는 문자로 구분한다는 차이점이 있다.
포장 클래스
자바는 기본 타입의 값을 갖는 객체를 생성할 수 있는데 이런 객체를 포장 객체라고 한다. 값을 포장하고 있다고 해서 붙여진 이름이다.
int, char타입만 포장 클래스가 Integer, Character이다.
포장 객체는 포장하고 있는 기본 타입의 값을 변경할 수 없고 단지 객체로 생성하는데 목적이 있다. 이런 객체가 필요한 이유는 컬렉션 객체 때문이다.
박싱과 언박싱
기본 타입의 값을 포장 객체로 만드는 과정을 박싱이라고 하고, 포장 객체에서 기본 타입의 값을 얻어내는 과정을 언박싱이라고 한다.
Integer obj = 100;
int value = obj;
int value = obj + 50; //언박싱 후 연산
문자열을 기본 타입 값으로 변환
포장 클래스는 문자열을 기본 타입 값으로 변환할 때도 사용된다. 대부분의 포장 클래스에는 'parse + 기본타입' 명으로 되어있는 정적 메소드가 있다. 이 메소드는 문자열을 해당 기본 타입 값으로 변환한다.
포장 값 비교
포장 객체는 내부 값을 비교하기 위해 ==와 != 연산자 사용불가하며 포장 객체 번지를 비교하는 것이기 때문에 내부 값을 비교하는 대에는 사용x.
수학 클래스
Math 클래스는 수학 계산에 사용할 수 있는 메소드를 제공한다. Math 클래스가 제공하는 메소드는 모두 정적이므로 Math 클래스로 바로 사용이 가능하다.
(나중에 하다보면 익숙해지겠져)
![](https://velog.velcdn.com/images/namsm17/post/1d2917bc-a272-4aa5-b150-d31a1f79c6fc/image.jpeg)
형식 클래스
Format 클래스 | 설명 |
---|
DecimalFormat | 숫자를 형식화된 문자열로 변환 |
SimpleDateFormat | 날짜를 형식화된 문자열로 변환 |
숫자를 형식화된 문자열로 변환하는 기능을 제공하며 원하는 형식으로 표현하기 위해 아래와 같은 패턴을 사용한다.![](https://velog.velcdn.com/images/namsm17/post/00c850dc-51cd-487f-ad34-e13fab0b4dc9/image.jpeg)
날짜를 형식화된 문자열로 변환하는 기능을 제공한다. 원하는 형식으로 표현하기 위해 아래와 같은 패턴을 사용한다. ![](https://velog.velcdn.com/images/namsm17/post/f84818e8-fd2d-444d-b0b4-433297486f1b/image.jpeg)
정규 표현식 클래스
문자열이 정해져 있는 형식으로 구성되어 있는지 검증해야 하는 경우가 있다. 예를 들어 이메일이나 전화번호를 사용자가 제대로 입력했는지 검증할 때이다. 자바는 정규 표현식을 이용해서 문자열이 올바르게 구성되어 있는지 검증한다.
정규 표현식은 문자 또는 숫자와 관련된 표현과 반복 기호가 결합된 문자열이다. 아래는 정규 표현식을 구성하는 표현 및 기호에 대한 설명이다.
![](https://velog.velcdn.com/images/namsm17/post/5bf6bc6a-e437-4c3b-9e8f-acef0a52643f/image.jpeg)
(02|010)-\d{3,4}-\d{4}
\w+@\w+\.\w+(\.\w+)?
pattern 클래스로 검증
java.util.regex 패키지의 pattern 클래스는 정규 표현식으로 문자열을 검증하는 matches() 메소드를 제공한다. 첫 번째 매개값은 정규 표현식이고, 두 번째 매개값은 검증할 문자열이다. 검증한 후의 결과는 boolean 타입으로 리턴된다.
boolean result = pattern.matches("정규식", "검증할 문자열");
리플렉션
자바는 클래스와 인터페이스의 메타 정보를 Class 객체로 관리한다. 여기서 메타 정보란 패키지 정보, 타입 정보, 멤버 정보 등을 말한다. 이러한 메타 정보를 프로그램에서 읽고 수정하는 행위를 리플렉션이라고 한다.
패키지와 타입 정보 얻기
메소드 | 용도 |
---|
Package getPackage() | 패키지 정보 읽기 |
String getSimpleName() | 패키지를 제외한 타입 이름 |
String getName() | 패키지를 포함한 전체 타입 이름 |
멤버 정보 얻기
타입이 가지고 있는 멤버 정보는 다음 메소드를 통해 얻을 수 있다.
메소드 | 용도 |
---|
Constructor[]getDeclaredConstructors() | 생성자 정보 읽기 |
Field[]getDeclaredFields() | 필드 정보 읽기 |
Method[]getDeclaredMethods() | 메소드 정보 읽기 |
어노 테이션
코드에서 @으로 작성되는 요소를 어노테이션이라고 한다. 어노테이션은 클래스 또는 인터페이스를 컴파일하거나 실행할 때 어떻게 처리해야 할 것인지를 알려주는 설정 정보이다.
컴파일 시 사용하는 정보 전달
빌드 툴이 코드를 자동으로 생성할 때 사용하는 정보 전달
실행 시 특정 기능을 처리할 때 정보 전달
컴파일 시 사용하는 정보 전달의 대표적인 예는 재정의 @Override 어노테이션이다. 어노테이션은 자바 프로그램을 개발할 때 필수 요소가 되었고 앞으로 배울 스프링 프레임워크 스프링 부트에 다양한 종류의 어노테이션을 사용하여 웹 애플리케이션을 설정한다.
어노테이션 타입 정의와 적용
어노테이션도 하나의 타입이므로 어노테이션을 사용하기 위해서는 먼저 정의부터 해야 한다. 어노테이션을 정의하는 방법은 인터페이스를 정의하는 것과 유사하다
public @interface AnnotationName {
}
이렇게 정의한 어노테이션은 코드에서 @AnnotationName으로 사용된다.
어노테이션은 속성을 가질 수 있는데, 속성은 타입과 이름으로 구성되며, 이름 뒤에 괄호를 붙인다. 속성의 기본값은 default 키워드로 지정할 수 있다.
어노테이션 적용 대상
자바에서 어노테이션은 설정 정보라고 했다. 그렇다면 어떤 대상에 설정 정보를 적용할 것인지, 즉 클래스에 적용할 것인지, 메소드에 적용할 것인지를 명시해야 한다. 적용할 수 있는 대상의 종류는 ElementType 열거 상수로 정의되어 있다.![](https://velog.velcdn.com/images/namsm17/post/3c37d7ed-a25d-4a5a-b032-ab99adffa8de/image.jpeg)
적용 대상을 지정할 때에는 @Target 어노테이션을 사용한다. @Target의 기본 속성인 value는 ElementType 배열을 값으로 가진다. 이것은 적용 대상을 복수 개로 지정하기 위해서이다.
어노테이션 유지 정책
어노테이션을 정의할 때 한가지 더 추가해야 할 내용은 @AnnotationName을 언제까지 유지할 것인지를 정하는 것이다.![](https://velog.velcdn.com/images/namsm17/post/ab5ae4a4-9f65-409b-adf7-eb0a6e8db4cc/image.jpeg)
애플 에어드랍 진짜 개사기
유지 정책을 지정할 때에는 @Retention 어노테이션을 사용한다. 기본 속성인 value는 RetentionPolicy 열거 상수 값을 가진다. 아래는 실행 시에도 어노테이션이 설정 정보를 이용할 수 있도록 유지 정책을 RUNTIME으로 한 것이다
@Target( { ElementType.TYPE, ElementType.FIELD, ElementType.METHOD } )
@Retention( RetentionPolicy.RUNTIME )
public @interface AnnotationName {
}
어노테이션 설정 정보 이용
어노테이션은 아무런 동작을 가지지 않는 설정 정보일 뿐이다. 이 설정 정보를 이용해서 어떻게 처리할 것인지는 애플리케이션의 몫이다. (리플렉션 이용)![](https://velog.velcdn.com/images/namsm17/post/9f8e11c9-c393-4527-812b-0f8913fa8867/image.jpeg)
확인문제
1. 4
2. 3
3. 4
4. hashCode, equals
5.
@Override
public boolean equals(Object obj){
if(obj instanceof Student){
Student student=(Student)obj;
if(studentNum.equals(student.getStudentNum())){
return true;
}
}
return false;
}
@Override
public int hashCode(){
return studentNum.hashCode();
}
6.
@Override
public String toString(){
return id+": "+name;
}
7. 3
8.
public class Example {
public static void main(String[] args) {
long start = System.nanoTime();
int[] scores = new int[1000];
for (int i = 0; i < scores.length; i++) {
scores[i] = i;
}
int sum = 0;
for (int score : scores) {
sum += score;
}
double avg = sum / scores.length;
System.out.println(avg);
long end = System.nanoTime();
System.out.println((end - start) + "ns");
}
}
9. new String(bytes, "UTF-8")
10.
public class StringBuilderExample {
public static void main(String[] args) {
String str = "";
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 100; i++) {
sb.append(i);
}
str = sb.toString();
System.out.println(str);
}
}
11.
public class StringTokenizerExample {
public static void main(String[] args) {
String str = "아이디,이름,패스워드";
StringTokenizer st = new StringTokenizer(str, ",");
while (st.hasMoreTokens()) {
String token = st.nextToken();
System.out.println(token);
}
}
}
12.
public class IntegerCompareExample {
public static void main(String[] args) {
Integer obj1 = 100;
Integer obj2 = 100;
Integer obj3 = 300;
Integer obj4 = 300;
System.out.println(obj1.equals(obj2));
System.out.println(obj3.equals(obj4));
}
}
13. 4
14. 4
15.
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class Example {
public static void main(String[] args) {
LocalDateTime startDateTime = LocalDateTime.now();
LocalDateTime endDateTime = LocalDateTime.of(startDateTime.getYear(), 12, 31, 0, 0, 0);
long remainDay = startDateTime.until(endDateTime, ChronoUnit.DAYS);
System.out.println("남은 일자: " + remainDay);
}
}
16.
import java.text.SimpleDateFormat;
import java.util.Date;
public class Example {
public static void main(String[] args) {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일 E요일 HH시 mm분");
System.out.println(sdf.format(now));
}
}
17. "[a-zA-Z][a-zA-Z0-9]{7,11}" Pattern.matches(regExp, id)
18. 4
19. 4