-
[자바의 정석] Ch.9 lang패키지와 유용한 클래스스터디플래너/공부하기 2022. 3. 29. 08:18
1. java.lang패키지
java.lang 패키지는 자바프로그래밍의 가장 기본이 되는 클래스 → import문 없이 java.lang패키지 사용 가능
1.1 Object클래스
https://docs.oracle.com/javase/7/docs/api/ Object 클래스는 멤버변수 없이 11개의 메서드가 있으나 notify(), notifyAll(), wait() 메서드는 쓰레드와 관련된 것으로 쓰레드에서 학습
clone()
자신을 복제하여 새로운 인스턴스를 생성. Object클래스의 clone()은 인스턴스변수의 값만 복사하기 때문에 참조타입의 인스턴스 변수가 있는 클래스는 완전히 복제할 수 없음. 다른 메소드와 마찬가지로 clone메소드를 오버라이딩하여 각 클래스의 목적에 맞게 사용해야 함.
clone메소드를 통해 복제하려면 인스턴스의 데이터를 보호하기 위해 Cloneable인터페이스를 구현한 클래스의 인스턴스이여야 함.
공변 반환타입
공변 반환타입(covariant return type)은 오버라이딩할 때 조상 메서드의 반환타입을 자손 클래스의 타입으로 변경을 허용하는 것
public Covariant clone(){ //반환타입을 Object에서 Covariant로 변경 Object obj = null; try{ obj = super.clone(); }catch(CloneNotSupportException e){ } return (Covariant)obj; //Covariant타입으로 형변환 } //Covariant copy = (Covariant)original.clone(); Covariant copy = original.clone();
java.util패키지의 Vector, ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, Calendar, Date와 같은 클래스들이 이 방식으로 복제할 수 있음
얕은 복사와 깊은 복사
clone()은 단순히 객체에 저장된 값을 그대로 복제할 뿐, 객체가 참조하고 있는 객체까지 복제하지 않는다. 객체배열을 clone()으로 복제하는 경우 원본과 복제본이 같은 객체를 공유하므로 완전한 복제라고 보기 어렵다. 이러한 복제를 '얕은 복제(shallow copy)'라고 한다. 얕은 복사에서는 원본을 변경하면 복사본도 영향을 받는다. 얕은 복사와 반대로 '깊은 복사(deep copy)'는 원본이 참조하고 있는 객체까지 복제한다. 깊은 복사는 원본과 복사본이 서로 다른 객체를 참조하기 때문에 원본의 변경이 복사본에 영향을 미치지 않는다.
class Circle implements Cloneable{ Point p; double r; Circle(Point p, double r){ this.p = p; this.r = r; } public Circle sahllowCopy(){ //얕은 복사 }
equals(Object obj)
public boolean equals(Object obj){ return(this==obj); }
매개변수로 객체의 참조변수를 받아 비교한 뒤 그 결과를 boolean값으로 반환. 두 객체의 같고 다름을 비교할 때는 참조변수의 값으로 판단하므로 서로 다른 두 객체를 equals메소드로 비교하면 항상 false를 반환. 두 참조변수가 저장된 주소값이 같은지를 판단하는 기능만 할 수 있음
public boolean equals(Object obj){ //obj인스턴스가 null이 아니면서 String클래스이고, 두 개의 길이가 같은지 확인 if(obj != null && obj instanceof String && this.length()==obj.length()){ for(int i=0; i<this.length(); i++){ if(this[i]==obj[o] } }else{ return fasle; } }
finalize()
가비지 컬렉션이 정리하지 못한 객체를 직접 가비지 컬랙터를 호출하여 정리
getClass()
자신이 속한 클래스의 Class객체를 반환하는 메서드. Class객체란 이름이 Class인 객체로 클래스의 모든 정보를 담고 있고 클래스당 1개만 존재. 클래스 로더(ClassLoader)에 의해서 메모리에 올라갈 때 자동으로 생성. 클래스 로더는 실행 시에 필요한 클래스를 동적으로 메모리에 로드하는 역할. 클래스 객체란 파일형태로 저장된 클래스를 읽어 Class클래스에 정의된 형식으로 변환하여 사용하기 편한 형태로 저장한 것.
Class객체를 얻는 방법
Class cobj = new Circle().getClass(); //생성된 객체로부터 얻는 방법 Class cobj = Circle.class; //클래스 리터럴(*.class)로부터 얻는 방법 Class cobj = Class.forName("Circle"); //클래스 이름으로부터 얻는 방법
hashCode()
해싱(hashing)기법에 사용되는 '해시함수(hash function)'를 구현한 것. 해싱이란 데이터관리기법 중 하나로, 다량의 데이터를 저장하고 검색하는데 유용. 해시함수는 찾고자하는 값을 입력하면, 그 값이 저장된 위치를 알려주는 해시코드(hashcode)를 반환. 해시코드가 같은 두 객체가 존재하는 것이 가능하나 Object클래스의 hashCode메소드는 객체의 주소값으로 해시코드를 만들어 반환하기 때문에 32bit JVM에서는 서로 다른 두 객체는 같은 해시코드를 가질 수 없지만 64bit JVM에서는 8byte 주소값으로 해시코드(4byte)를 만들기 때문에 중복될 수 있음.
String클래스는 문자열의 내용이 동일하면 동일한 해시코드를 반환하도록 hashCode메소드가 오버라이딩 되어이있어 문자열이 서로 같은 str1과 str2에 hashCode()를 호출하면 항상 동일한 해시코드값을 얻음. System.identityHashCode(Object x)는 Object클래스의 hashCode메소드처럼 객체의 주소값으로 해시코드를 생성하기 때문에 모든 객체가 다른 해시코드값을 얻음.
toString()
인스턴스 정보에 대한 정보를 문자열로 제공. Object클래스에 정의된 toString()은 아래와 같아 클래스를 작성할 때 toString()을 오버라이딩 하지 않으면 아래와 같은 16진수 해시코드값을 사용해야 함.
String클래스의 toString()은 String인스턴스가 갖고 있는 문자열을 반환하도록 오버라이딩되어 있고, Date클래스의 toString()은 Date인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하여 반환하도록 오버라이딩 되어 있음
1.2. String클래스
변경 불가능한(immutable)클래스
String클래스는 문자열을 저장하기 위해 문자형 배열 참조변수(char[]) value를 인스턴스 변수로 정의. 인스턴스 생성 시 생성자의 매개변수로 입력받는 문자열이 인스턴스변수 value에 문자형 배열로 저장됨. '+'연산자를 이용해서 문자열을 결합하는 경우 인스턴스 내 문자열이 바뀌는 것이 아니라 새로운 문자열이 담긴 String인스턴스가 생성됨. 이렇게 String인스턴스를 계속 생성하는 경우 메모리공간을 차지하게 되므로 가능한 한 결합횟수를 줄이는 것이 좋음. 계속 생성해야하는 경우 String클래스보다 변경이 가능한 StringBuffer클래스를 사용하는 것이 좋음.
String str1 = "a"; //str1 = 0x100(a) String str2 = "b"; //str2 = 0x200(b) str1 = str + str2; //str1 = 0x300(ab)
문자열의 비교
String클래스의 생성자를 이용하는 경우 new연산자에 의해서 메모리할당이 이루어지기 때문에 항상 새로운 String인스턴스가 생성됨. 문자열 리터럴은 이미 존재하는 것을 재사용
String str1 = "abc"; //str1 = 0x100; String str2 = "abc"; //str2 = 0x100; String str3 = new String("abc"); //str3 = 0x200; String str4 = new String("abc"); // str4 = 0x300;
문자열 리터럴
클래스 파일에는 소스파일에 포함된 모든 리터럴의 목록이 있음. 해당 클래스 파일이 클래스 로더에 의해 메모리에 올라갈 때, 이 리터럴 목록에 있는 리터럴들이 JVM내에 있는 상수 저장소(constant pool)에 저장됨.
빈 문자열(empty string)
String str = "";
str가 참조하고 있는 String인스턴스는 내부에 길이가 0인 char형 배열을 저장하고 있는 것(new char[0]). char형 변수는 반드시 하나의 문자를 지정해야 함. 초기화할 때 String은 null보다 "", charg는 \u0000대신 공백으로 초기화
String클래스의 생성자와 메소드
메소드 설명 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 concat(String str) 문자열 str를 뒤에 덧붙임 boolean contains(CharSequence s) 지정된 문자열 s가 포함이 되었는지 여부를 검사 boolean endsWith(String suffix) 지정된 문자열 suffix로 끝나는지 검사 boolean equals(Object obj) 사매개변수로 받은 문자열obj와 String인스턴스의 문자열을 비교하여 다르면 false반환 boolean equalsIgnoreCase(String str) 문자열과 String인스턴스의 문자열을 대소문자 구분없이 비교 int indexOf(int ch) 주어진 문자열 ch가 문자열에 존재하는지 확인하여 위치를 알려주고, 못 찾으면 -1을 반환 int indexOf(int ch, int pos) 주어진 문자열 ch가 문자열에 존재하는지 지정된 위치pos부터 확인하여 위치를 알려주고, 못 찾으면 -1을 반환 int indexOf(String str) 주어진 문자열 str가 문자열에 존재하는지 확인하여 위치를 알려주고, 못찾으면 -1을 반환 String intern() 문자열을 상수풀(constant pool)에 등록. 이미 상수풀에 같은 내용의 문자열이 있을 경우 그 문자열의 주소값을 반환 int lastIndexOf(int ch) 지정된 문자 또는 문자코드를 문자열의 오른쪽 끝에서부터 찾아서 위치를 알려주고, 못 찾으면 -1을 반환 int lastIndexOf(String str) 지정된 문자열을 인스턴스의 문자열 끝에서부터 찾아서 그 위치를 알려주고, 못 찾으면 -1을 반환 int length() 문자열의 길이를 알려줌 String replace(char old, char nw) 문자열 중 old문자를 새로운 문자 nw로 모두 바꾼 문자열을 반환 String replace(CharSequence old, CharSequence nw) 문자열 중 old문자열을 새로운 문자열 nw로 모두 바꾼 문자열을 반환 String replaceAll(String regex, String replacement) 문자열 중의 지정된 문자열 regex와 일치하는 것을 모두 새로운 문자열replacement로 변경 String replaceFirst(String regex, String replacement) 문자열 중 지정된 문자열 regex와 일치하는 것 중 첫 번째 것만 새로운 문자열 replacement로 변경 String[] split(String regex) 문자열을 지정된 문자열 regex로 나누어 문자열 배열에 담아 반환 String[] split(String regex, int limit) 문자열을 지정된 문자열 regex로 나누어 문자열 배열에 담아 반환하되,문자열 전체를 지정된 수 limit으로 자름 boolean startsWith(String prefix) 주어진 문자열 prefix로 시작하는지 검사 String substring(int begin)
String substring(int begin, int end)주어진 시작위치부터 끝 혹은 end까지 범위에 포함된 문자열을 얻음. 시작위치는 범위에 포함되지만 끝위치는범위에 포함되지 않음 String toLowerCase() String인스턴스에 저장되어있는 모든 문자열을 소문자로 변환하여 반환 String toString() String인스턴스에 저장되어 있는 문자열을 반환 String toUpperCase() String인스턴스에 저장되어 있는 모든 문자열을 대문자로 변환하여 반환 String trim() 문자열의 왼쪽 끝과 오른쪽 끝에 있는 공백을 없앤 결과를 반환. 문자열 중간에 있는 공백은 제거되지 않음 static String valueOf(boolean b)
static String valueOf(char c)
static String valueOf(int i)
static String valueOf(long l)
static String valueOf(float f)
static String valueOf(double d)
static String valueOf(Object o)지정된 값을 문자열로 변환하여 반환. 참조변수의 경우 toString()을 호출한 결과를 반환 join()과 StringJoiner
join()은 여러 문자열 사이에 구분자를 넣어서 결합. 구분자로 문자열을 자르는 split()과 반대.
유니코드의 보충문자
유니코드(2byte)는 16비트 문자체계였으나 모자라서 20비트로 확장 → 하나의 문자를 char타입이 아니라 int타입으로 다루게 됨. 16비트 → 20비트로 늘어나며 새로 추가하게 된 문자들을 '보충 문자(supplementary characters)'라 함. 매개변수가 int ch인 것들은 보충문자를 지원.
문자 인코딩 변환
getBytes(String charSetName)를 사용하면, 문자열의 문자 인코딩을 다른 인코딩으로 변경할 수 있음
String.format()
format()은 형식화된 문자열을 만들어내는 간단한 방법
기본형 값을 String으로 변환
숫자에 빈 문자열("")을 더해주거나 valueOf()를 사용
int i = 100; String str1 = i + ""; String str2 = String.valueOf(i);
String을 기본형 값으로 변환
valueOf()를 사용하거나 parseInt를 사용. valueOf()의 반환타입은 int가 아니라 Integer이지만 오토박싱(auto-boxing)에 의해 Integer가 int로 자동 변환. valueOf()는 메소드 내부에서 parseInt()를 호출하므로 valueOf()와 parseInt()는 반환타입만 다를 뿐 같은 메소드.
parseInt() parseFloat()같은 메소드는 문자열에 공백 또는 문자가 포함되어 있는 경우 변환 시 예외(NumberFlormatException)가 발생할 수 있으므로, 문자열 양 끝에 공백을 제거해주는 trim()을 같이 사용하기도 함. 그러나 부호를 의미하는 '+'나 소수점을 의미하는 '.', float형을 뜻하는 f와같은 자료형 접미사는 허용
1.3. StringBuffer클래스와 StringBuilder클래스
String클래스는 인스턴스를 생성할 때 지정된 문자열을 변경할 수 없지만 StringBuffer클래스는 변경이 가능함. 내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffer인스턴스를 생성할 때 그 크기를 지정할 수 있음. StringBuffer클래스는 String클래스와 같이 문자열을 저장하기 위한 char형 배열의 참조변수를 인스턴스변수로 선언. StringBuffer인스턴스가 생성될 때, char형 배열을 생성되고 이 char형 배열을 인스턴스변수 value가 참조.
StringBuffer의 생성자
StringBuffer클래스의 인스턴스를 생성할 때 , char형 배열이 만들어지는데 이 배열이 문자열을 저장하고 편집하기 위한 공간(buffer)으로 사용. 이 버퍼의 크기를 지정해주지 않으면 16개의 문자를 저장할 수 있는 크기의 버퍼를 생성. 버퍼의 크기가 작업하려는 문자열의 크기보다 작을 때는 내부적으로 버퍼의 크기를 증가시키는 작업을 수행.
StringBuffer의 변경
StringBuffer sb = new StringBuffer("abc"); sb.append("123"); System.out.println(sb); //"abc123"
StringBuffer클래스의 append메소드는 자기 자신(StringBuffer)의 주소를 반환하여 내용을 변경할 수 있음. 반환타입이 void였다면 변경할 수 없음.
StringBuffer의 비교
String클래스는 equals메소드를 오버라이딩하여 문자열을 비교할 수 있지만, StringBuffer클래스는 equals메소드를 오버라이딩하지 않아 equals메소드를 사용해도 등가비교연산자(==)를 사용한 것과 동일한 결과를 얻음. 하지만 toString메소드는 오버라이딩되어 있기 때문에 toString메소드로 StringBuffer인스턴스를 String인스턴스로 얻은 다음 equals메소드를 사용하면 비교할 수 있음.
StringBuffer클래스의 생성자와 메소드
메소드 설명 StringBuffer() 16문자를 담을 수 있는 버퍼를 가진 StringBuffer인스턴스를 생성 StringBuffer(int length) 지정된 개수의 문자를 담을 수 있는 버퍼를 가진 StringBuffer인스턴스를 생성 StringBUffer(String str) 지정된 문자열 값(str)을 갖는 StringBuffer 인스턴스를 생성 StringBuffer append(booelan b)
StringBuffer append(char c)
StringBuffer append(char[] str)
StringBuffer append(double d)
StringBuffer append(float f)
StringBuffer append(int i)
StringBuffer append(long l)
StringBuffer append(Object obj)
StringBuffer append(String str)매개변수로 입력된 값을 문자열로 변환하여 StringBuffer인스턴스가 저장하고 있는 문자열의 뒤에 덧붙임 Int capacity() StringBUffer인스턴스의 버퍼크기를 알려줌. length()는 버퍼에 담긴문자열의 길이를 알려줌. char charAt(int index) 지정된 위치 index에 있는 문자를 반환. StringBuffer delete(int start, int end) 시작위치 start부터 끝 위치end 사이에 있는 문자를 제거하되 끝 위치 문자는 제외 StringBuffer insert(int pos, boolean b)
StringBuffer insert(int pos, char c)
StringBuffer insert(int pos, char[] str)
StringBuffer insert(int pos, double d)
StringBuffer insert(int pos, float f)
StringBuffer insert(int pos, int i)
StringBuffer insert(int pos, long l)
StringBuffer insert(int pos, Object obj)
StringBuffer insert(int pos, String str)두번째 매개변수로 받은 값을 문자열로 변환하여 지정된 위치 pos에 추가 Int length() StringBuffer에 저장되어 있는 문자열의 길이를 반환 StringBuffer replace(int start, int end, String str) 지정된 범위(start~end)의 문자들을 주어진 문자열로 바꿈. StringBuffer reverse() StringBuffer인스턴스에 저장되어 있는 문자열의 순서를 거꾸로 나열 void setCharAt(int index, char ch) 지정된 위치의 문자를 주어진 문자 ch로 바꿈 void setLength(int newLength) 지정된 길이로 문자열의 길이를 변경. 길이를 늘리는 경우 나머지 빈 공간은 널문자 '\u0000'로 채움 String toString() StringBuffer인스턴스의 문자열을 String으로 변환 String substring(int start)
String substring(int start, int end)지정된 범위 내의 문자열을 String으로 뽑아서 반환. 시작위치만 지정하면 시작위치부터 끝까지 문자열로 변환 StringBufilder란?
StringBuffer는 멀티쓰레드에 안전하도록 동기화되어있으나 동기화가 StringBuffer의 성능을 저하시킴. StringBuffer에 쓰레드의 동기화만 뺀 StringBuilder가 등장. StringBuilder는 StringBuffer와 완전히 동일한 기능을 하므로 StringBuffer타입의 참조변수를 선언한 부분과 생성자를 StringBuilder로 바꿔주면 됨.
1.4. Math클래스
Math클래스의 생성자는 접근 제어자가 private이기 때문에 다른 클래스에서 Math인스턴스를 생성할 수 없음. 클래스 내에 인스턴스 변수가 없어 인스턴스를 생성할 필요가 없음.
올림, 버림, 반올림
소수 n번째 자리에서 반올림한 값을 얻기 위해서는 round()를 사용해야 하나 round()는 항상 소수 첫째짜리에서 반올림하여 정수값을 돌려 줌. 소수 첫번째 자리까지 값을 얻고싶다면 10, 두번째 자리 100, 세번째 자리 1000을 곱하고 Math.round()를 사용한 다음 각각 10.0, 100.0, 1000.0으로 나누면 됨
double val = 90.7522; double val1 = val * 10; double val2 = val * 100; double val3 = val * 100; val1 = Math.round(val) / 10.0; //소수 첫번째 자리까지 val2 = Math.round(val) / 100.0; //소수 두번째 자리까지 val3 = Math.round(val) / 1000.0; //소수 세번째 자리까지
예외를 발생시키는 메서드
int addExact(int x, int y) //x+y int substractExact(int x, int y) //x-y int multiplyExact(int x, int y) //x*y int incrementExact(int a) //a++ int decrementExact(int a) //a-- int negateExact(int a) //-a int toIntExact(long value) //(int)value
연산자를 연산을 수행하다하면 오버플로우가 발생할 수 있음. 오버플로우가 발생하면 예외(ArithmeticException)을 발생.
삼각함수와 지수, 로그
StrictMath클래스
StrictMath클래스는 어떤 OS에서 실행되어도 항상 같은 결과를 얻도록 Math클래스를 새로 작성함
Math클래스의 메소드
메소드 설명 static double abs(double a)
static float abs(float f)
static int abs(int f)
static long abs(long f)주어진 값의 절대값을 반환 static double ceil(double a) 주어진 값을 올림하여 반환 static double floor(double a) 주어진 값을 버림하여 반환 static double max(double a, double b)
static float max(float a, float b)
static int max(int a, int b)
static long max(long a, long b)주어진 두 값을 비교하여 큰 쪽을 반환 static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)주어진 두 값을 비교하여 작은 쪽을 반환 static double random() 0.0~1.0범위의 임의의 double값을 반환 static double rint(double a) 주어진 double값과 가장 가까운 정수값을 double형으로 반환. 두 정수 중 정가운데있는 값은 짝수로 반환 static long round(double a)
static long round(float a)소수점 첫째자리에서 반올림한 정수값을 반환. 매개변수의 값이 음수인 경우 round()와 rint()의 결과가 다름 1.5. 래퍼(wrapper)클래스
java에서는 8개의 기본형을 객체로 다루지 않아 완전한 객체지향이 아니라는 이야기를 듣는 대신, 높은 성능을 얻을 수 있었음. 기본형 변수도 객체로 다뤄야 할 때 사용하는 것이 래퍼(wrapper)클래스로, 8개의 기본형을 대표하는 8개의 래퍼클래스가 있고 이를 이용하면 기본형값 객체를 다룰 수 있음.
래퍼 클래스는 모두 equals()가 오버라이딩되어 있어서 주소값이 아닌 객체가 갖고있는 값을 비교. toString()도 오버라이딩되어 있어 객체가 가지고 있는 값을 문자열로 반환. 그 외에도 MAX_VALUE, MIN_VALUE, SIZE, BYTES, TYPE 등 static상수를 공통적으로 가짐.
Number클래스
래퍼클래스는 Number클래스의 자손들. Number클래스에는 8개의 기본형을 다루는 8개의 래퍼클래스 외에도 BigInteger와 BigDecimal이 있는데, 각각 long과 double로 다룰 수 없는 큰 범위의 수를 처리함
문자열을 숫자로 변환하기
래퍼 클래스의 '타입.parse타입(String s)'형식의 메소드와 '타입.valueOf()'메소드로 문자열을 숫자로 바꿀 수 있음. 전자는 기본형 타입으로, 후자는 래퍼 클래스로 반환하는 것이 차이. valueOf()는 내부에서 parse메소드를 사용하므로 성능이 조금 더 느림.
오토박싱 & 언박싱(autoboxing & unboxing)
기본형과 참조형 간의 연산이 불가능하여 래퍼클래스로 기본형을 객체로 만들어서 연산해야 했으나 JDK1.5이후 컴파일러가 Integer객체를 int타입으로 변환해주는 intValue()를 추가하여 변환없이 연산할 수 있도록 만들어줌. 그 밖에 Vector클래스나 ArrayList클래스에 기본형 값을 저장해야 할 때나 형변환이 필요한 경우 컴파일러가 자동으로 코드를 추가해 줌. 이렇게 기본형 값을 래퍼 클래스의 객체로 자동 변환해주는 것을 '오토박싱(autoboxing)', 반대로 변환하는 것을 '언박싱(unboxing)'이라 함
'스터디플래너 > 공부하기' 카테고리의 다른 글
[자바의 정석] Ch.11 컬렉션 프레임웍(Collections Framework) (0) 2022.05.10 [자바의 정석] Ch.9-2. java.lang패키지와 유용한 클래스 (0) 2022.04.06 [자바의 정석] Ch.8 예외처리 (0) 2022.03.22 [자바의 정석] Chapter07-3. 객체지향 프로그래밍2 (0) 2022.03.15 [자바의 정석] Chapter07-2. 객체지향 프로그래밍2 (0) 2022.03.01