👉🏻 이 글은 자바의 정석(3판) Chapter9을 공부하며 쓴 글입니다.
java.lang 패키지는 자바프로그래밍에 가장 기본이 되는 클래스들을 포함하고 있다. 그렇기 때문에
import문 없이 사용할 수 있게 되어있다.
Object 클래스는 모든 클래스의 최고 조상이기 때문에 Object 클래스의 멤버들은 모든 클래스에서 바로 사용 가능하다.
| Object 클래스의 메서드 | 설명 |
|---|---|
| protected Object clone() | 객체 자신의 복사본을 반환한다 |
| public boolean equals(Object obj) | 객체 자신과 객체 obj가 같은 객체인지 알려준다. |
| protected void finalize() | 객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출된다. 이 때 수행되어야 하는 코드가 있을 때 오버라이딩한다. |
| public Class getClass() | 객체 자신의 클래스 정보를 담고 있는 Class인스턴스를 반환 |
| public int hashCode() | 객체의 해시코드 반환 |
| public String toString() | 객체 자신의 정보를 문자열로 반환 |
| public void notify() | 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨운다. |
| public void notifyAll() | 객체 자신을 사용하려고 기다리는 쓰레드를 모두 깨운다. |
| public void wait() | 다른 쓰레드가 notify()나 notifyAll()을 호출할 때까지 현재 쓰레드를 무한히 또는 지정된 시간동안 기다리게 한다. |
| public void wait(long timeout) | timeout은 천분의 1초이다. |
| public void wait(long timeout, int nanos) | nanos는 10의 9승 분의 1초이다. |
: 자신을 복제하여 새로운 인스턴스를 생성하는 함수이다.
원래의 인스턴스는 보존하고 clone() 메서드를 이용해서 새로운 인스턴스를 생성하여 작업을 하면 작업 이전의 값이 보존되므로 작업에 실패해서 원래의 상태로 되돌리거나 변경되기 전의 값을 참고하는데 도움이 될 것이다.
class Point implements Cloneable{ //1.Cloneable 인터페이스 구현
...
public Object clone() { //2.접근제어자 public으로 변경
Object obj = null;
try{
obj = super.clone(); //3.try-catch 내에서 조상클래스의 clone()을 호출
}catch(CloneNotSupportedException e) {}
return obj;
}
}
+연산자를 이용한 문자열의 결합을 기존 변수에 대입할 경우 문자열이 바뀌는 것이 아니라 새로운 문자열이 담긴 String인스턴스가 생성되어 대입되는 것이다.equals()를 사용하면 두 문자열의 내용을 비교하지만 ==을 사용하면 String인스턴스의 주소를 비교하게 되므로 String의 내용을 비교하려면 equals()를 쓰는 것이 맞다.
+ ) 길이가 0인 빈 문자열도 생성 가능하다. -> String s = "";
but, char형은 이러한 초기화가 불가능하다. 따라서 보통 char c = " "; 공백을 이용하는 것이 일반적이다.
| Object 클래스의 메서드 | 설명 |
|---|---|
String(String s) | 문자열 s를 갖는 String 인스턴스를 생성한다. |
String(char[] value) | 문자열 value를 갖는 String 인스턴스를 생성한다. |
String(StringBuffer buf) | StringBuffer인스턴스가 갖고 있는 문자열과 같은 내용의 String인스턴스를 생성한다. |
char charAt(int index) | 지정된 위치(index)에 있는 문자를 알려준다. |
int compareTo(String str) | 문자열(str)과 사전 순서로 비교한다. 같으면 0, 사전순으로 이전이면 음수, 이후면 양수 반환. |
String concate(String str) | 문자열을 뒤에 덧붙인다. |
boolean contains(CharSequence s) | 지정된 문자열(suffix)로 끝나는지 검사한다. |
boolean endWith(String suffix) | 매개변수로 받은 문자열과 String인스턴스의 문자열을 비교한다. String이 아니거나 문자열이 다르면 false를 반환한다. |
boolean equalsIgnoreCase(String str) | 문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교한다. |
int indexOf(int ch) | 주어진 문자가 문자열에 존재하는지 확인하여 위치를 알려준다. 못 찾으면 -1을 반환한다. |
int indexOf(int ch, int pos) | 지정된 위치(pos)부터 확인하여 위치를 알려준다. |
int indexOf(String str) | 주어진 문자열이 존재하는지 확인하여 그 위치를 알려준다. |
String intern() | 문자열을 상수풀(constant pool)에 등록한다. 이미 상수풀에 같은 내용의 문자열이 있을 경우 주소값을 반환한다. |
int lastIndexOf(int ch) | 지정된 문자 또는 문자코드를 문자열의 오른쪽 끝부터 찾아서 위치를 알려준다. 못 찾으면 -1 |
int lastIndexOf(String str) | 지정된 문자열을 인스턴스의 문자열 끝에서부터 찾아서 위치(index) 반환 |
int length() | 문자열의 길이를 알려준다. |
String replace(char old, char nw) | 문자열 중의 문자(old)를 새로운 문자(nw)로 바꾼 문자열을 반환 |
String replace(CharSequence old, CharSequence nw) | 문자열(old) 중의 문자열을 새로운 문자열(nw)로 모두 바꾼 문자열을 반환한다. |
String replaceAll(String regex, String replacement) | 문자열 중에 지정된 문자열과 일치하는 것을 새로운 문자열로 모두 변경한다. |
String replaceFirst(String regex, String replacement) | 일치하는 것 중, 첫번째만 새로운 문자열로 변경한다. |
String[] split(String regex) | 문자열을 지정된 분리자로 나누어 문자열 배열에 담아 반환한다. |
String[] split(String regex, int limit) | 문자열을 지정된 분리자로 나누어 문자열 배열에 담아 반환. 단, 문자열 전체를 지정된 개수(limit)로 자른다. |
boolean startsWith(String prefix) | 주어진 문자열로 시작하는지 검사. |
String substring(int begin) , String substring(int begin, int end) | 주어진 시작위치부터 끝 위치 범위에 포함된 문자열을 얻는다. 이때, 끝 위치의 문자는 포함되지 않는다.(begin<= x < end) |
String toLowerCase() | 모든 문자열을 소문자로 변환하여 반환한다. |
String toString() | String인스턴스에 저장되어 있는 문자열을 반환한다. |
String toUpperCase() | 모든 문자열을 대문자로 변환하여 반환한다. |
String trim() | 문자열의 왼쪽 끝과 오른쪽 끝의 공백을 제거한 결과를 반환한다. 중간 공백은 제거하지 않는다. |
static String valueOf(...) | 지정된 값을 문자열로 변환하여 반환. 참조변수의 경우, toString()을 호출한 결과를 반환한다. |
join()은 여러 문자열 사이에 구분자를 넣어서 결합한다.String str = String.join("-", arr);
StringJoiner sj = new StringJoiner(",", "[", "]");
String[] strArr = {"aaa", "bbb", "ccc"};
for(String s: strArr)
sj.add(s.toUpperCase());
System.out.println(sj.toString());
// 결과: [AAA,BBB,CCC]
int i = 10;
String str1 = i + "";
String Str2 = String.valueOf(i);
int i = Integer.parseInt("100");
int i2 = Integer.valueOf("100");
: StringBuffer 클래스는 문자열 변경이 가능하다. 내부적으로 문자열 편집을 위한 buffer를 가지고 있으며, 인스턴스를 생성할 때 그 크기 지정이 가능하다.
StringBuffer 인스턴스가 생성될 때, char형 배열이 생성되며 이 배열을 인스턴스 변수 value가 참조하게 된다.
public final class StringBuffer implements java.io.Serialization {
private char[] value;
...
public StringBuffer(int length){
value = new char[length];
shared = false;
}
public StringBuffer(){
this(16); // 크기 지정 안하면 버퍼의 크기는 16.
}
public StringBuffer(String str){
this(str.length() + 16); // 지정한 문자열의 길이보다 16이 더 크게 버퍼 생성
append(str);
}
...
}
이 배열은 문자열을 저장하고 편집하기 위한 공간인 buffer로 사용된다.
인스턴스를 생성할 때, 생성자 StringBuffer(int length)를 사용해서 저장될 문자열의 길이를 고려해 충분히 여유있는 크기로 지정하는 것이 좋다.
위 코드는 배열의 길이를 변경하는 내용의 코드이다. 배열의 길이는 변경될 수 없으므로 새로운 길이의 배열을 생성한 후에 이전 배열의 값을 복사해야 한다.
StringBuffer의 변경
StringBuffer sb = new StringBuffer("abc");
sb.append("123"); // abc123
StringBuffer sb2 = sb.append("ZZ");
System.out.println(sb); // abc123ZZ
System.out.println(sb2); // abc123ZZ
sb와 sb2 모두 같은 StringBuffer인스턴스를 가리키고 있다.
toString()은 오버라이딩 되어있어서 toString을 호출하여 String인스턴스를 얻은 다음, equals메서드를 사용해서 비교해야 한다.⬇️ StringBuffer 역시 문자열을 다루기 위한 것이기 때문에 String클래스와 유사한 메서드들을 많이 가지고 있다. 거기에 추가, 변경, 삭제와 같은 메서드들을 추가로 제공한다.
| 메서드 | 설명 |
|---|---|
StringBuffer append(...) | 매개변수로 입력된 값을 문자열로 변환하여 인스턴스가 저장하고 있는 문자열의 뒤어 덧붙인다. |
int capacity() | 인스턴스의 버퍼 크기를 알려준다. (length()는 버퍼에 담긴 문자열의 길이를 알려준다.) |
StringBuffer delete(int start, int end) | 시작 위치부터 끝 위치의 바로 전까지에 있는 문자를 제거한다. |
StringBuffer deleteCharAt(int index) | 지정된 위치의 문자를 제거한다. |
StringBuffer insert(int pos, boolean b), StringBuffer insert(int pos, char ch), StringBuffer insert(int pos, char[] str), ... | 두 번째 매개변수로 받은 값을 문자열로 변환하여 지정된 위치(pos)에 추가한다. |
StringBuffer replace(int start, int end, String str) | 지정된 범위의 문자들을 주어진 문자열로 바꾼다. |
StringBuffer reverse() | 인스턴스에 저장되어 있는 문자열의 순서를 거꾸로 나열한다. |
void setLength(int newLength) | 지정된 길이로 문자열의 길이를 변경한다. 길이를 늘리는 경우에 나머지 빈 공간을 \u0000으로 채운다 |
: StringBuffer는 멀티쓰레드에 thread safe하도록 동기화되어 있다. 이는 StringBuffer의 성능을 저하시키므로 StringBuffer에서 동기화만 뺀 StringBuilder가 새로 추가되었다.
기능은 완전히 같으므로 소스코드에서 StringBuffer타입의 참조변수를 선언한 부분과 StringBuffer의 생성자만 바꾸면 된다.
StringBuffer도 충분히 성능이 좋기 때문에 반드시 필요한 경우를 제외하고는 기존 코드에서 굳이 바꿀 필요는 없다.
Math클래스에는 이름에서 알 수 있듯이 수학 관련 메서드들이 있다.
자세한 내용은 Java API(자바에서 기본적으로 제공하고 있는 명령어들)를 참고하면 알 수 있다.
➡️ Java API 11 : https://docs.oracle.com/en/java/javase/11/docs/api/index.html
자바에서는 8개의 기본형을 객체로 다루지 않았는데, 이것이 바로 자바가 완전한 객체지향 언어가 아니라는 얘기를 듣는 이유이다. 그 대신 보다 높은 성능을 얻을 수 있었다.
때로는 기본형 변수도 어쩔 수 없이 객체로 다뤄야 하는 경우가 있다.
👉🏻이 때 래퍼클래스를 사용한다.
| 기본형 | 래퍼클래스 | 생성자 |
|---|---|---|
| boolean | Boolean | Boolean(boolean value), Boolean(String s) |
| char | Character | Character(char value) |
| byte | Byte | Byte(byte value), Byte(String s) |
| short | Short | Short(short value), Short(String s) |
| int | Integer | Integer(int value), Integer(String s) |
| long | Long | Long(long value), Long(String s) |
| float | Float | Float(double value), Float(float value), Float(String s), |
| double | Double | Double(double value), Double(String s) |
래퍼 클래스들은 모두 equals()가 오버라이딩되어 있어서 주소값이 아닌 객체가 가지고 있는 값을 비교한다.
toString()도 오버라이딩되어 있어서 객체가 가지고 있는 값을 문자열로 변환하여 반환한다.
BigInteger, BigDemical를 자손으로 가지는 클래스이다.
long으로 다룰 수 없는 큰 범위의 정수를, double로 다룰 수 없는 큰 범위의 부동 소수점수를 처리하기 위한 것이다.
아래 유용한 클래스에서 다시 다룬다.
문자열 -> 기본형
byte b = Byte.parseByte("100");
short s = Short.parseShort("100");
int i = Integer.parseInt("100");
...
문자열 -> 래퍼클래스
Byte b = Byte.valueOf("100");
Short s = Short.valueOf("100");
Integer i = Integer.valueOf("100");
...
👉🏻 JDK1.5 이전에는 기본형과 참조형 간의 연산이 불가능했기 때문에, 래퍼클래스로 기본형을 객체로 만들어서 연산해야 했다.
그러나 JDK1.5부터 도입된 "오토박싱" 기능 때문에 반환값이 기본형일 때와 래퍼 클래스일 때의 차이가 없어졌다. 그래서 구별없이 valueOf()를 쓰는 것도 괜찮은 방법이다. 하지만 성능은 valueOf()가 조금 더 느리다.
아래는 java.util 패키지에 수많은 클래스들이 있지만 그중에서도 자주 사용되는 중요한 클래스들이다.
Object클래스의 보조 클래스.
static이다.null 체크에 유용하다.static boolean isNull(Object odj)
static boolean nonNull(Object odj)
// 해당 객체가 널이 아니어야 하는 경우에 사용
// 만일 객체가 널이면 NullPointerException 발생시킨다.
static <T> T requireNonNull(T obj)
static <T> T requireNonNull(T obj, String message)
☝⬆️
// 유효성 검사
if(name == null)
throw new NullPointerException("name numst not be null.");
매개변수의 유효성 검사를 생략하고 위 호출만으로 간단히 끝낼 수 있다.
: java.util.regex 패키지