11장 매번 만들기 귀찮은데 누가 만들어 놓은 거 쓸 수 없나요?
1. API (Application Programming Interface)
애플리케이션에 선언되어 있는 클래스와 메소드에 대한 상세한 설명이 포함된 문서
2. javadoc
jdk/bin 디렉터리에 있는 javadoc이라는 명령어를 실행해주면 자동으로 API 문서인 HTML 파일이 생성
3. Deprecated
더 이상 사용하지 않는 생성자, 상수 필드, 메소드
12장 모든 클래스의 부모 클래스는 Object에요
java.lang.Object
모든 클래스의 부모 클래스 즉, 아무런 상속을 받지 않으면 Object 클래스를 확장한다
- 왜 모든 클래스는 Object 클래스의 상속을 받을까?
→ Object 클래스에 있는 메소드들을 통해서 클래스의 기본적인 행동을 정의 가능하기 때문
Object 클래스의 메소드
- 객체를 처리하기 위한 메소드
메소드 | 설명 |
protected Object clone() | 객체의 복사본을 만들어 리턴 |
public boolean equals(Object obj) | 현재 객체와 매개 변수로 넘겨받은 객체가 같은지 확인, 같으면 true 다르면 false |
protected void finalize() | 현재 객체가 더 이상 쓸모 없어졌을 때 가비지 컬렉터에 의해서 이 메소드가 호출됨 |
public Class<?> getClass() | 현재 객체의 Class 클래스의 객체를 리턴 |
public int hashCode() | 객체에 대한 해시코드 값을 리턴 (해시 코드: 16진수로 제공되는 객체의 메모리 주소) |
public String toString() | 객체를 문자열로 표현하는 값을 리턴 |
★ 가비지 컬렉터(garbage collector): 자바의 메모리에 있는 쓰레기를 청소하는 로봇
- 쓰레드를 위한 메소드
메소드 | 설명 |
public void notify() | 이 객체의 모니터에 대기하고 있는 단일 쓰레드를 깨운다 |
public void notifyAll() | 이 객체의 모니터에 대기하고 있는 모든 쓰레드를 깨운다 |
public void wait() | 다른 쓰레드가 현재 객체에 대한 notify() 메소드나 notifyAll()메소드를 호출할 때까지 현재 쓰레드가 대기하고 있도록 한다 |
public void wait(long timeout) wait() | 메소드와 동일한 기능을 제공 + 매개 변수에 지정한 시간만큼만 대기 |
public void wait(long timeout, int nanos) wait() | 메소드와 동일한 기능을 제공 |
toString()
- System.out.println() 메소드에 매개 변수로 들어가는 경우
- 객체에 대하여 더하기 연산을 하는 경우
toString()으로 출력된 결과
getClass().getName() + '@' + Integer.toHexString(hashCode())
// 현재 클래스의 패키지 이름과 클래스 이름 + '@' + 객체의 해시 코드 값
Overriding
public class MemberDTO{
public String name;
public String phone;
public String toString(){
return "Name = " + name + " Phone = " + phone;
}
}
★ 모든 클래스의 toString() 메소드를 Overriding할 필요는 없지만 DTO를 사용할 때는 해주는 게 좋다
eqauls()
★ ==와 != 연산자는 기본 자료형에서만 사용 가능, 참조 자료형에서는 값이 아니라 주소 값을 비교
★ 참조 자료형을 비교하려면 eqauls() 사용
public void eqaulMethod(){
MemberDTO obj1 = new MemberDTO("TEST");
MemberDTO obj2 = new MemberDTO("TEST"); // 각각의 생성자를 사용하여 만듦 -> 주소 값 다름
if(obj1 == obj2){
System.out.println("same");
}else{
System.out.println("different");
}
}
// 결과
different
- eqauls() 메소드를 Overriding 할 때 필수 조건
- 재귀 reflexive
: null이 아닌 x라는 객체의 x.equals(x) 결과는 항상 true여야만 한다
- 대칭 symmetric
: null이 아닌 x와 y 객체가 있을 때 y.equals(x)가 true를 리턴했다면, x.eqauls(y)도 true를 리턴해야 한다
- 타동적 transitive
: null이 아닌 x,y,z가 있을 때 x.eqauls(y)가 true를 리턴하고, y.eqauls(z)가 true를 리턴하면, x.eqauls(z)는 반드시 true를 리턴해야 한다
- 일관 consistent
: null이 아닌 x와 y가 있을 때 객체가 변경되지 않은 상황에서는 몇 번을 호출하더라도 x.eqauls(y)의 결과는 항상 true이거나 항상 false여야만 한다
- null과의 비교
: null이 아닌 x라는 객체의 x.eqauls(null) 결과는 항상 false여야만 한다
- eqauls() 메소드를 Overriding할 때는 hashCode() 메소드도 같이 Overriding해야 한다
- eqauls() 메소드만 사용하면 객체는 같지만 객체의 주소 값은 다를 수 있기 때문에 같은 hashCode() 메소드를 갖도록 해야한다
hashCode()
객체의 고유 값인 메모리 주소를 16진수로 리턴
- hashCode() 메소드를 Overriding할 때 필수 조건
- 자바 애플리케이션이 수행되는 동안에 어떤 객체에 대해서 이 메소드가 호출될 때에는 항상 동일한 int 값을 리턴해 주어야 한다. 하지만 자바를 실행할 때마다 같은 값이어야 할 필요는 없다
- 어떤 두 개의 객체에 대하여 equals() 메소드를 사용하여 비교한 결과가 true일 경우에, 두 객체의 hashCode() 메소드를 호출하면 동일한 int 값을 리턴해야 한다
- 두 객체를 eqauls() 메소드를 사용하여 비교한 결과 false를 리턴했다고 해서, hashCode() 메소드를 호출한 int 값이 무조건 달라야 할 필요는 없다. 하지만 이 경우에 서로 다른 int 값을 제공하면 hashtable의 성능을 향상시키는데 도움 된다
→ equals()나 hashCode()는 개발 툴을 이용해 자동 생성하는 것을 권장
13장 인터페이스와 추상클래스, enum
방법론
분석 → 설계 → 개발 및 테스트 → 시스템 릴리즈
interface
- DAO(Data Access Object)
: 데이터를 저장하는 저장소에서 원하는 값을 요청하고 응답을 받는다
- 인터페이스와 abstract 클래스를 사용하는 이유
- 설계 시 선언해 두면 개발할 때 기능을 구현하는 데에만 집중 가능
- 개발자의 역량에 따른 메소드의 이름과 매개 변수 선언의 격차를 줄일 수 있음
- 공통적인 인터페이스와 abstract 클래스를 선언해 놓으면, 선언과 구현을 구분 가능
인터페이스 선언
public interface MemberManager{
public boolean addmember(MemberDTO member); // member를 추가하는 메소드
public boolean removeMember(String name, String phone); // member를 지우는 메소드
public boolean updateMember(MemberDTO member); // member를 수정하는 메소드
}
// 인터페이스 내부에 선언된 메소드들은 몸통(body)가 있으면 안됨
// static이나 final 메소드 선언 불가
인터페이스 활용
public class MemberManagerImpl implements MemberManager{
// MemberManager에 정의된 메소드들을 모두 구현해야만 컴파일 가능
@Override
public boolean addMemer(memberDTO member)
return false;
}
@Override
public boolean removeMember(String name, String phone)
return false;
}
@Override
public boolean updateMember(memberDTO member)
return false;
}
}
publci class InterfaceExample{
public static void main(String args[]){
MemberManager member = new MemberManagerImpl();
// MemberManagerImpl 클래스에는 인터페이스에 선언된 모든 메소드들이 구현되어있음
}
}
implements
extends를 이용한 상속은 다중 상속이 불가능하지만 implements를 이용해 클래스를 구현하는 것은 여러 개 가능
abstract 클래스
메소드가 구현되지 않은, 인터페이스에 있는 메소드 선언문들과 같이 몸통이 없이 선언한 것
- 마음대로 초기화하고 실행 불가
- abstract 클래스를 구현해 놓은 클래스로 초기화 및 실행 가능
public interface MemberManager{ public boolean addmember(MemberDTO member); public boolean removeMember(String name, String phone); public boolean updateMember(MemberDTO member); }
public abstract class MemberManagerAbstract{ public abstract boolean addmember(MemberDTO member); public abstract boolean removeMember(String name, String phone); public abstract boolean updateMember(MemberDTO member); }
- abstract 클래스는 클래스 선언시 abstract라는 예약어를 클래스 앞에 추가
- abstract 클래스 안에는 abstract로 선언된 메소드가 0개 이상 있으면 가능
- abstract으로 선언된 메소드가 하나라도 있으면, 그 클래스는 반드시 abstract로 선언되어야 함
- abstract 클래스는 body가 있는 메소드가 0개 이상 있어도 상관 없고, static이나 final 메소드가 있어도 가능
- implements라는 예약어 사용 불가 → 인터페이스가 아니라 클래스이기 때문에 extends로 상속 가능
- extends로 상속 받은 클래스는 abstract으로 선언된 메소드들을 구현해야 한다
→ 인터페이스와 abstract 클래스의 상속을 받으면 구현되지 않은 메소드들을 구현해야 한다
인터페이스 | abstract 클래스 | 클래스 | |
예약어 | interface | abstract class | class |
구현 안 된 메소드 포함 가능 여부 | 가능(필수) | 가능 | 불가 |
구현된 메소드 포함 가능 여부 | 불가 | 가능 | 가능(필수) |
static, final 메소드 선언 가능 여부 | 불가 | 가능 | 가능 |
extends, implements | implements | extends | extends |
final
클래스, 메소드, 변수
public final class FinalClass{
// 상속 불가 클래스
}
public abstract class FinalMethodClass{
public final void prinLog(String data){
// Override 불가 메소드
}
}
public class FinalVariable{
final int instanceVariable=1; // 변하지 않는 값 = 상수(constant)
// 인스턴스 변수나 클래스 변수(static)는 생성과 동시에 초기화 필수
public void method(final int parameter){
final int localVariable; // 매개변수나 지역변수를 final로 선언한 경우는 선언할 때 초기화 할 필요 없음
}
enum (enumeration) 열거형 클래스
클래스가 상수만으로 만들어져 있을 경우 enum으로 선언하면 별도로 타입, 값을 지정할 필요 X
public enum OverTimeValues{
THREE_HOUR,
FIVE_HOUR,
WEEKEND_FOUR_HOUR,
WEEKEND_EIGHT_HOUR;
}
System.out.println(OverTimeValues.THREE_HOUR); // enum클래스이름.상수이름
- enum 상수 값을 지정 가능 but 값을 동적으로 할당은 불가
- 생성자는 package-private과 private만 접근제어자로 사용 가능
→ 각 상수를 enum 클래스 내에서 선언할 때만 이 생성자를 사용 가능
public enum OverTimeValues{
THREE_HOUR(18000),
FIVE_HOUR(30000),
WEEKEND_FOUR_HOUR(40000),
WEEKEND_EIGHT_HOUR(60000);
private final int amount;
OverTimeValues2(int amount){ // public, protected 불가
this.amount = amount
}
}
- java.lang.Enum
1. enum 클래스는 무조건 java.lang.Enum 클래스의 상속을 받음 → 다중 상속이 안되므로 extends 불가
접근제어자 | 메소드 | 설명 |
protected | Enum(String name, int ordinal) | 컴파일러에서 자동으로 호출되도록 해놓은 생성자 |
2. Object 클래스의 메소드 (enum 클래스에서 clone()과 finalize()는 사용하지 말기)
Overriding 가능여부 | 메소드 | 내용 |
불가능 | clone() | 객체를 복제하기 위한 메소드 → CloneNotSupportedException |
불가능 | finalize() | GC가 발생할 때 처리하기 위한 메소드 |
불가능 | hashCode() | int 타입의 해시 코드 값을 리턴 |
불가능 | equals() | 두 개의 객체가 동일한지 확인 |
가능 | toString() | 객체를 문자열로 표현하는 값을 리턴 |
3. Enum 클래스의 메소드
메소드 | 내용 |
compareTo(E e) | 매개 변수로 enum 타입과의 순서 차이를 리턴 |
getDeclaringClass() | 클래스 타입의 enum을 리턴 |
name() | 상수의 이름을 리턴 |
ordinal() | 상수의 순서를 리턴 |
valueOf(Class<T> enumType, String name) | static 메소드, 첫 번째 매개 변수로는 클래스 타입의 enum을, 두 번째 매개변수로는 상수의 이름을 넘김 |
14장 다 배운 것 같지만, 예외라는 중요한 것이 있어요
예외 (exception)
우리가 예상한, 혹은 예상치 못한 일이 발생하는 것을 미리 예견하고 안정장치를 하는 것
try-catch
// 예외 발생
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at c.exceptionExceptionSample.arrayOutOfBounds(ExceptionSample.java:11)
at c.exceptionExceptionSample.main(ExceptionSample.java:7)
// at + call stack trace
public void arrayOutOfBoundsTryCatch(){
try{
int[] intArray = new int[5];
System.out.println(intArray[5]); // 예외가 발생하는 문장들
}catch (Exception e){
System.err.println("Exception occured."); // 예외가 발생했을 때 처리
}
}
- try 블록 내에서 예외가 발생하면?
→ 예외가 발생한 줄 이후에 있는 try 블록 내의 코드들을 수행되지 않고 catch 블록에 있는 문장이 실행
- try 블록 내에서 예외가 발생하지 않으면?
→ catch 내에 있는 코드는 실행되지 않는다
finally
어떠한 경우에도 실행되는 블록
public void finallySample(){
int[] intArray = new int[5]; // catch에서 사용하는 변수는 try 블록 앞에 선언
try{
System.out.println(intArray[5]);
}catch (Exception e){
System.out.println(intArray.length);
}finally{
System.out.println("Finally");
}
}
- finally 블록은 예외 발생 여부와 상관 없이 실행
java.lang.Exception
모든 예외의 부모 클래스는 java.lang.Exception
- catch 블록은 1개 이상 가능
- 먼저 선언한 catch 블록의 예외 클래스가 다음에 선언한 catch 블록의 부모에 속하면, 자식에 속하는 catch 블록은 절대 실행될 일이 없으므로 컴파일이 되지 않는다
ex) Exception 클래스가 먼저 선언되어있을 경우 - 하나의 try 블록에서 예외가 발생하면 그 예외와 관련이 있는 catch 블록을 찾아서 실행함
- catch 블록 중 발생한 예외와 관련있는 블록이 없으면 예외가 발생되면서 해당 쓰레드는 끝
public void finallySample(){
int[] intArray = new int[5]; /
try{
intArray = null;
System.out.println(intArray[5]);
}catch (NullPointerException e){
System.out.println("NullPointerException occurred");
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsException occurred");
}catch (Exception e){
System.out.println("java.lang.Exception");
}
예외의 종류
checked exception
- error와 runtime exception을 제외한 모든 예외
- Exception을 확장한 클래스들
- ex) IOException, SQLException, MalformedURLException …
error
- 자바 프로그램 밖에서 발생한 예외
- ex) 서버의 디스크 고장, 메인보드 고장 등
- error와 exception 차이
runtime exception (unchecked exception)
- 예외가 발생할 것을 미리 감지하지 못했을 때 발생 → 컴파일 시 체크하지 않았기 때문에 unchecked exception이라고도 함
- RuntimeException을 확장한 예외들
- ex) NullPointerException, NumberFormatException, ClassCastException, IndexOutOfBoundsException …
java.lang.Throwable
- Exception과 Error의 공통 부모 클래스는 Object 클래스와 Throwable 클래스
→ Exception 처리 시 Throwable로 처리해도 무관
→ Exception과 Error의 성격은 다르지만 모두 동일한 이름의 메소드를 사용하여 처리할 수 있음
Throwable 생성자
- Throwable()
- Throwable(String message) : 예외 메시지
- Throwable(String message, Throwable cause) : 예외 메시지, 예외의 원인
- Throwable(Throwable cause)
Throwable 메소드
- getMessage() : 예외 메시지를 String 형태로 출력
- toString() : getMessage() 보다 자세한 예외 메시지를 String 형태로 출력
- printStackTrace() : 예외 메시지와 예외가 발생하게 된 메소드들의 호출 관계(스택 트레이스) 출력// getMessage()의 출력 결과
/* NullPointerException 발생 시 */
// getMessage()의 출력 결과
null
// toString()의 출력 결과 (예외 클래스 이름 포함)
java.lang.NullPointerException
// printStackTrace()의 출력 결과
java.lang.NullPointerException
at c.exception.ThrowableSample.throwable(ThrowableSample.java:12)
at c.exception.ThrowableSample.main(ThrowableSample.java:6)
예외 던지기
public void throwException(int number){
try{
if(number > 12){
throw new Exception("Number is over than 12");
}
System.out.println("Number is " + number);
}catch (Exception e){
e.printStackTrace();
}
}
- try 블록 내에 throw라고 명시 후 예외 클래스의 객체를 생성하여 예외를 던짐
- number가 13이면 throw한 문장 이후에 있는 try 블록 내의 문장들은 수행되지 않고, catch 블록으로 이동
- catch 블록 중에 throw한 예외와 동일하거나 상속 관계에 있는 예외가 있다면 그 블록에서 예외 처리 가능
public void throwsException(int number) throws Exception{
if(number > 12){
throw new Exception("Number is over than 12");
}
System.out.println("Number is " + number);
}
- catch 블록 중에 throw한 예외가 없다면 예외가 발생된 메소드를 호출한 메소드로 던짐
- 메소드에 선언해 놓으면 try-catch로 묶어주지 않아도 그 메소드를 호출한 메소드로 예외 처리를 위임
→ throwsException() 메소드를 호출한 메소드에서는 반드시 try-catch 블록으로 묶어줘야 함
public static void mina(String args[]){
ThrowSample sample = new ThrowSample();
try{
sample.throwsException(13);
}catch(Exceptin e){
e.printStackTrace();
}
}
예외 클래스 확장
public class MyException extends Exception{
public MyException() { super(); }
public MyException(String message){ super(message); }
}
// 예외 관련 클래스를 확장해 예외를 만들고 catch블록에서 사용
try{
if(number>12){
throw new MyException("Number is over than 12");
}
}catch (MyException e){
e.printStackTrace();
}
- extends Exception
- extends RumTimeException
- Throwable의 직계 자손 클래스들을 상속받아 생성
15장 String
String 클래스
public final class String extends Object implements Serializable, Comparable<String>, CharSequence
// final 클래스: String을 상속 불가
- Serializable 인터페이스: 구현해야 하는 메소드가 하나도 없는 인터페이스
→ implements Serializable: 해당 객체를 파일로 저장하거나 다른 서버에 전송 가능한 상태가 됨 - Comparable 인터페이스: compareTo() 메소드만 선언되어 있는 인터페이스
→ 매개 변수로 넘어가는 객체와 현재 객체가 같은지를 비교할 때 사용
→ 같으면 0, 순서 상으로 앞에 있으면 -1, 뒤에 있으면 1을 리턴 (객체의 순서 처리 가능) - CharSequence 인터페이스: 해당 클래스가 문자열을 다루기 위한 클래스라는 것을 명시적으로 나타내는 데 사용
ex) StringBuilder, StringBuffer에서 CharSequence 인터페이스를 구현
String 생성자
★ 캐릭터 셋: 문자의 집합 (한글, 일본어 등)
★ 디코딩: 암호화되어 있거나 컴퓨터가 이해할 수 있는 값들을 알아보기 쉽게 변환
- String의 생성자는 더 많음 → 각각의 생성자를 사용할 필요가 있을 때 API에서 찾아 사용하기
byte 변환
- String 클래스에는 현재의 문자열 값을 byte 배열로 변환하는 메소드가 존재
리턴 타입 | 메소드 | 설명 |
byte[] | getBytes() | 기본 캐릭터 셋의 바이트 배열을 생성 |
byte[] | getBytes(Charset charset) | 지정한 캐릭터 셋 객체 타입으로 바이트 배열을 생성 |
byte[] | getBytes(String charsetName) | 지정한 이름의 캐릭터 셋을 갖는 바이트 배열을 생성 |
- 캐릭터 셋
캐릭터 셋 이름 | 설명 |
US-ASCII | 7비트 아스키 |
UTF-16 | 16비트 UCS 변환 포맷 (한글 처리) |
★ 잘못된 캐릭터셋으로 변환하면 글자가 깨지는 현상이 발생 |
→ byte 배열로 생성할 때 사용한 캐릭터 셋을 문자열로 다시 전환할 때에도 동일하게 사용하기
byte[] array1 = korean.getBytes("UTF-16"); // byte 배열로 생성할 때 UTF-16 사용
String stringArray = new String(array1, "UTF-16"); // String으로 전환할 때 UTF-16 사용
// 존재하지 않는 캐릭터 셋을 사용할 경우 UnsupportedEncodingException 발생 -> try-catch
★EUC-KR : 한글 2글자 = 4byte
★UTF-16 : 한글 2글자 = 6byte
null 체크
- 객체가 널인지 아닌지 체크하는 것은 == 연산자와 != 연산자로 확인 가능
if(text==null){
return true;
}
String 메소드
1. 문자열의 길이를 확인하는 메소드 (legnth : 배열의 크기를 확인)
int | length() | 문자열의 길이를 리턴 |
public void checkString(){
String text = "JiYoon HaHa";
System.out.println("text 길이 " + text.length());
}
// 결과 (공백 포함)
text 길이 = 11
2. 문자열이 비어있는지 확인하는 메소드
boolean | isEmpty() | 문자열이 비어있으면 true, 아니면 false를 리턴 |
public void checkString(){
String text = "JiYoon HaHa";
System.out.println("text Empty" + text.isEmpty());
}
// 결과
text Empty = false
3. 문자열이 같은지 비교하는 메소드
boolean | equals(Object anObject) |
boolean | equalsIgnoreCase(String anotherStr) |
int | comapreTo(String anotherStr) |
int | compareToIgnoreCase(String str) |
boolean | contentEquals(CharSequence sc) |
boolean | contentEquals(StringBuffer sb) |
- 모두 매개변수로 넘어온 값과 String 객체가 같은지 비교하기 위한 메소드
- IgnoreCase가 붙은 메소드들은 대소문자 구분을 안함
public void checkCompare(){
String text1 = "Check value";
String text2 = "Check value";
String text3 = new String("Check value");
if(text1 == text2){
System.out.println("text1, text2 Same");
} else{
System.out.println("text1, text2 different");
}
if(text1.equals("Check value")){
System.out.println("text equals text2");
}
if(text1 == text3){
System.out.println("text1, text3 Same");
} else{
System.out.println("text1, text3 different");
}
// 결과
text1, text2 Same
text equals text2
text1, text3 different
- Constant Pool: 자바에서는 객체들을 재사용하기 위해 Constant Pool이 존재
→ String의 경우 동일한 값을 갖는 객체가 있으면 이미 만든 객체를 재사용 - text1과 text2는 동일한 값을 가지기 때문에 실제로는 같은 객체
- text3는 String 객체를 새로 생성했기 때문에 Constant Pool의 값을 재활용하지 않고 별도의 객체를 생성
public void checkComapreTo(){
String text1 = "a";
String text2 = "b";
String text3 = "c";
System.out.println(text2.compareTo(text1)); // text1은 text2보다 앞에 있으므로 양수 (1칸)
System.out.println(text2.compareTo(text3)); // text3은 text2보다 뒤에 있으므로 음수 (1칸)
System.out.println(text1.compareTo(text3)); // text3은 text1보다 뒤에 있으므로 음수 (2칸)
}
// 결과
1
-1
-2
- compareTo() 메소드는 보통 정렬할 때 사용
public void checkContentEquals(){
String text1 = "ab";
String text2 = "ab";
StringBuffer sb = new StringBuffer("ab");
System.out.println("text1 equals text2 = " + text1.equals(text2));
System.out.println("text1 equals sb = " + text1.equals(sb));
System.out.println("text1 contentEquals text2 = " + text1.contentEquals(text2));
System.out.println("text1 contentEquals sb = " + text1.contentEquals(sb));
}
// 결과
text1 equals text2 = true
text1 equals sb = false
text1 contentEquals text2 = true
text1 contentEquals sb = true
- equlas()는 String 끼리의 문자열이 동일한지 확인
- contentEqulas()는 매개변수로 넘어오는 CharSequence와 StringBuffer 객체가 String 객체와 같은지를 비교
4. 특정 조건에 맞는 문자열이 있는지를 확인하는 메소드
boolean | startsWith(String prefix) | 매개 변수로 넘겨준 값으로 시작하는 지 확인 |
boolean | endsWith(String suffix) | 매개 변수로 넘겨준 값으로 끝나는 지 확인 |
boolean | contains(CharSequence s) | 매개 변수로 넘겨준 값이 존재하는 지 확인 |
boolean | matches(String regex) | 매개 변수로 넘겨준 값이 정규 표현식으로 존재하는 지 확인 |
★indexOf() 메소드로도 찾을 수 있지만 indexOf() 메소드는 문자열의 모든 내용을 다 확인
5. 문자열 내에서 위치를 찾아내는 메소드
int | indexOf(String str) | 가장 왼쪽부터 문자열을 찾음 |
int | lastIndexOf(String str) | 가장 오른쪽부터 문자열을 찾음 |
★매개 변수에 (int ch) (int ch, int fromIndex) 도 존재 → char은 정수형이기 때문에 자동 형변환
6. 문자열의 일부를 추출하기 위한 메소드
(1) char 단위의 값을 추출하는 메소드
char | charAt(int index) | 특정 위치의 char 값을 리턴 |
void | getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) | 매개 변수로 넘어온 dst라는 char 배열 내에 srcBegin에서 srcEnd에 있는 char를 저장 이 때, dst 배열의 시작 위치는 dstBegin |
int | codePointAt(int index) | 특정 위치의 유니코드 값을 리턴 |
int | codePointBefore(int index) | 특정 위치 앞에 있는 char의 유니코드 값을 리턴 |
int | codePointCount(int beginIndex, int endIndex) | 지정한 범위에 있는 유니코드 개수를 리턴 |
int | offsetByCodePoints(int index, int codePointOffset) | 지정된 index부터 오프셋이 설정된 인덱스를 리턴 |
(2) char 배열의 값을 String으로 변환하는 메소드
static String | copyValueOf(char[] data) | char 배열에 있는 값을 문자열로 변환 |
static String | copyValueOf(char[] data, int offset, int count) | char 배열에 있는 값을 offset 위치부터 count까지의 개수만큼만 문자열로 변환 |
(3) String의 값을 char 배열로 변환하는 메소드
char[] | toCharArray() | 문자열을 char 배열로 변환하는 메소드 |
(4) 문자열의 일부 값을 잘라내는 메소드
String | substring(int beginIndex) | beginIndex부터 끝까지 대상 문자열을 잘라 String으로 리턴 |
String | substring(int beginIndex, int endIndex) | beginIndex부터 endIndex까지 대상 문자열을 잘라 String으로 리턴 |
CharSequence | subSequence(int beginIndex, int endIndex) | beginIndex부터 endIndex까지 대상 문자열을 잘라 CharSequence 타입으로 리턴 |
(5) 문자열을 여러 개의 String 배열로 나누는 split 메소드
String[] | split(String regex) | regex에 있는 정규 표현식에 맞춰 문자열을 잘라 String의 배열로 리턴 |
String[] | split(String regex, int limit) | String 배열의 크기를 limit으로 제한 |
★정규 표현식을 사용하여 문자열을 나누려고 한다면 String 클래스의 split() 메소드 사용
★특정 String으로 문자열을 나누려고 한다면 StringTokenizer 클래스를 사용
7. 문자열을 합치는 메소드
String | concat(String str) | 매개 변수로 받은 str을 기존 문자열의 우측에 붙인 새로운 문자열 객체를 생성하여 리턴 |
★concat() 메소드 보다는 StringBuffer나 StringBuilder 사용
8. 공백을 없애는 메소드
String | trim() | 문자열의 맨 앞과 맨 뒤에 있는 공백들을 제거한 문자열 객체를 리턴 |
String text = " a ";
if(text != null && text.trim().length() > 0 ){
System.out.println("공백을 제외한 값이 있다");
}
- 공백을 제외한 값이 있는지 확인하기 편리 → null 체크
9. 내용을 교체하는 메소드
String | replace(char oldChar, char newChar) | 해당 문자열에 있는 oldChar 값을 newChar로 대치 |
String | replaceAll(String regex, String replacement) | 해당 문자열의 내용 중 regex에 표현된 정규 표현식에 포함되는 모든 내용을 replacement로 대치 |
String | replaceFirst(String regex, String replacement) | 해당 문자열의 내용 중 regex에 표현된 정규 표현식에 포함되는 첫번째 내용을 replacement로 대치 |
★replace 메소드를 수행한다고 해서 기존 문자열의 값은 바뀌지 않음
★대소문자 구분
10. 특정 형식에 맞춰 값을 치환하는 메소드
static String | format(String format. Object… args) | format에 있는 문자열의 내용 중 변환해야 하는 부분을 args의 내용으로 변경 |
- %s : String
- %d : 정수형
- %f : 소수점이 있는 숫자
- %% : %
public void checkFormat(){
String text = "이름 = %s, 나이 = %d";
System.out.println(String.format(text, "바보", 26));
}
// 결과
이름 = 바보, 나이 = 26
★출력만 해도 된다면 System.out.format() 사용해도 무방
11. 대소문자를 바꾸는 메소드
String | toLowerCase() | 모든 문자열의 내용을 소문자로 변경 |
String | toUpperCase() | 모든 문자열의 내용을 대문자로 변경 |
12. 기본 자료형을 문자열로 변환하는 메소드
static String | valueOf(int i) | 기본 자료형을 String 타입으로 변환 |
byte b = 1;
String byte1 = String.valueOf(b);
String byte2 = b + " ";
// 모두 String 변환 O
// 문자열과 합치는 과정이 있다면 valueOf() 사용안해도 됨
13. intern() 메소드는 사용하지 말기
- intern() 메소드는 new String()으로 생성한 문자열 객체라고 할지라도 풀에 해당 값이 있으면 풀에 있는 값을 참조하는 객체를 리턴하고 동일한 문자열이 존재하지 않으면 풀에 해당값을 추가
→ 성능 저하 올 수도 있음
StringBuffer, StringBuilder
- String은 immutable한 객체 (불변 객체): 한번 만들어지면 더이상 그 값을 바꿀 수 없다
ex) String 문자열을 더하면 새로운 String 객체가 생성되고 기존 객체는 버림 - StringBuffer와 StringBuilder는 문자열을 더하더라도 새로운 객체를 생성하지 않음
- StringBuffer: Thread safe 하다 / StringBuilder: Thread safe하지 않다
- append() 메소드를 사용하여 문자열을 더함
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" world");
String | StringBuffer | StringBuilder | |
인터페이스 | CharSequnece 인터페이스 | CharSequnece 인터페이스 | CharSequnece 인터페이스 |
불변/가변 | 불변 객체 | 가변 객체 | 가변 객체 |
Thread safe | O | O | X |
★ 하나의 메소드 내에서 문자열을 생성하여 더할 경우 StringBuilder
★ 어떤 클래스에 문자열을 생성하여 더하기 위한 문자열을 처리하기 위한 인스턴스 변수가 선언되었고, 여러 쓰레드에서 이 변수를 동시에 접근하는 일이 있을 경우에는 반드시 StringBuffer 사용
'STUDY > Java' 카테고리의 다른 글
<자바의 신> 21장 실수를 방지하기 위한 제네릭이라는 것도 있어요 (0) | 2023.12.09 |
---|---|
<자바의 신> 16장 클래스 안에 클래스가 들어갈 수도 있구나 (0) | 2023.12.09 |
<자바의 신> 6장 제가 조건을 좀 따져요 (0) | 2023.12.09 |
<자바의 신> 1장 프로그래밍이란 무엇인가? (0) | 2023.12.09 |
아파치 톰캣(Apache-Tomcat) 설치 (0) | 2021.11.05 |