본문 바로가기

STUDY/Java

<자바의 신> 11장 매번 만들기 귀찮은데 누가 만들어 놓은 거 쓸 수 없나요?

11장 매번 만들기 귀찮은데 누가 만들어 놓은 거 쓸 수 없나요?

1. API (Application Programming Interface)

애플리케이션에 선언되어 있는 클래스와 메소드에 대한 상세한 설명이 포함된 문서

 

2. javadoc

jdk/bin 디렉터리에 있는 javadoc이라는 명령어를 실행해주면 자동으로 API 문서인 HTML 파일이 생성

 

3. Deprecated

더 이상 사용하지 않는 생성자, 상수 필드, 메소드

 

 


 

 

12장 모든 클래스의 부모 클래스는 Object에요

java.lang.Object

모든 클래스의 부모 클래스 즉, 아무런 상속을 받지 않으면 Object 클래스를 확장한다
  • 왜 모든 클래스는 Object 클래스의 상속을 받을까?

→ Object 클래스에 있는 메소드들을 통해서 클래스의 기본적인 행동을 정의 가능하기 때문

 

 

Object 클래스의 메소드

  1. 객체를 처리하기 위한 메소드
메소드 설명
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): 자바의 메모리에 있는 쓰레기를 청소하는 로봇

 

  1. 쓰레드를 위한 메소드
메소드 설명
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 할 때 필수 조건
  1. 재귀 reflexive

: null이 아닌 x라는 객체의 x.equals(x) 결과는 항상 true여야만 한다

  1. 대칭 symmetric

: null이 아닌 x와 y 객체가 있을 때 y.equals(x)가 true를 리턴했다면, x.eqauls(y)도 true를 리턴해야 한다

  1. 타동적 transitive

: null이 아닌 x,y,z가 있을 때 x.eqauls(y)가 true를 리턴하고, y.eqauls(z)가 true를 리턴하면, x.eqauls(z)는 반드시 true를 리턴해야 한다

  1. 일관 consistent

: null이 아닌 x와 y가 있을 때 객체가 변경되지 않은 상황에서는 몇 번을 호출하더라도 x.eqauls(y)의 결과는 항상 true이거나 항상 false여야만 한다

  1. null과의 비교

: null이 아닌 x라는 객체의 x.eqauls(null) 결과는 항상 false여야만 한다

  • eqauls() 메소드를 Overriding할 때는 hashCode() 메소드도 같이 Overriding해야 한다
  • eqauls() 메소드만 사용하면 객체는 같지만 객체의 주소 값은 다를 수 있기 때문에 같은 hashCode() 메소드를 갖도록 해야한다

 

hashCode()

객체의 고유 값인 메모리 주소를 16진수로 리턴
  • hashCode() 메소드를 Overriding할 때 필수 조건
  1. 자바 애플리케이션이 수행되는 동안에 어떤 객체에 대해서 이 메소드가 호출될 때에는 항상 동일한 int 값을 리턴해 주어야 한다. 하지만 자바를 실행할 때마다 같은 값이어야 할 필요는 없다
  2. 어떤 두 개의 객체에 대하여 equals() 메소드를 사용하여 비교한 결과가 true일 경우에, 두 객체의 hashCode() 메소드를 호출하면 동일한 int 값을 리턴해야 한다
  3. 두 객체를 eqauls() 메소드를 사용하여 비교한 결과 false를 리턴했다고 해서, hashCode() 메소드를 호출한 int 값이 무조건 달라야 할 필요는 없다. 하지만 이 경우에 서로 다른 int 값을 제공하면 hashtable의 성능을 향상시키는데 도움 된다

→ equals()나 hashCode()는 개발 툴을 이용해 자동 생성하는 것을 권장

 


 

13장 인터페이스와 추상클래스, enum

방법론

분석 → 설계 → 개발 및 테스트 → 시스템 릴리즈

 

interface

  • DAO(Data Access Object)

: 데이터를 저장하는 저장소에서 원하는 값을 요청하고 응답을 받는다

  • 인터페이스와 abstract 클래스를 사용하는 이유
  1. 설계 시 선언해 두면 개발할 때 기능을 구현하는 데에만 집중 가능
  2. 개발자의 역량에 따른 메소드의 이름과 매개 변수 선언의 격차를 줄일 수 있음
  3. 공통적인 인터페이스와 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); }
  1. abstract 클래스는 클래스 선언시 abstract라는 예약어를 클래스 앞에 추가
  2. abstract 클래스 안에는 abstract로 선언된 메소드가 0개 이상 있으면 가능
  3. abstract으로 선언된 메소드가 하나라도 있으면, 그 클래스는 반드시 abstract로 선언되어야 함
  4. abstract 클래스는 body가 있는 메소드가 0개 이상 있어도 상관 없고, static이나 final 메소드가 있어도 가능
  5. implements라는 예약어 사용 불가 → 인터페이스가 아니라 클래스이기 때문에 extends로 상속 가능
  6. 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 사용