티스토리 뷰
java.lang 패키지
- 자바 프로그래밍의 가장 기본이 되는 클래스들을 포함하고 있다.
- 따라서 import 문 없이도 사용할 수 있게 되었다.
- 가령) String, System, Object들이 있다.
Object
- 모든 클래스의 최고 조상이다.
- 메서드
- clone() : 객체 자신의 복사본을 반환
- 자신을 복제하여 새로운 인스턴스를 생성한다.
- equals(Object obj) : 객체 자신과 객체 obj가 같은 객체인지 알려준다. (인스턴스 비교, 값비교가 아니다.)
- 문자열의 경우에는 String에서 equal을 오버라이딩하여 값비교로 바꾸었기 때문에 가능한 것이다.
- finalize() : 가비지 컬렉터에 의해 삭제될 때 불리는 호출자
- getClass() : 클래스 인스턴스를 반환
- hashCode() : 객체 자신의 해시코드를 반환
- 같은 객체라면 같은 값으로 나온다.
- toString() : 객체 자신의 정보를 문자열로 반환
- notify() : 객체 자신을 사용하려고 기다릴는 쓰레드를 하나만 깨운다.
- notifyAll() : 객체 자신을 사용하려고 기다리는 모든 쓰레드를 깨운다.
- wait(), wait(long timeout) , wait(long timeout, int nanos) : 다른 쓰레드가 notify()나 notfyAll()을 호출할 때 까지 현재 쓰레드를 무한히 또는 지정된 시간동안 기다리게 한다.
- clone() : 객체 자신의 복사본을 반환
clone
현재의 인스턴스를 복사하는 역할을 한다.
그러나 완벽히 복사하는 것이 아니라, 인스턴스 변수의 값만 복사한다는 단점이 있다.
즉, 참조 변수가 가리키고 있는 주소 값을 복사하는 것이지, 새로 인스턴스를 만들어서 값을 복사하는 것이 아니다.
가령, 배열의 경우 복제된 인스턴스도 같은 배열의 주소를 갖기 대문에 복제된 인스턴스의 작업이 원래의 인스턴스에도 영향을 미친다.
clone을 하려면 복제할 클래스가 Cloneable 인터페이스를 구현해야하고 clone()을 오버라이딩하면서 접근제어자를 protected에서 public으로 변경한다.
그래야만 상속관계가 없는 다른 클래스에서 clone()을 호출할 수 있다.또한 부모 클래스에서의 super을 사용하려면 try - catch 구문을 반드시 사용해주어야 한다.
class Point implements Cloneable{ public Object clone() { Object obj = null; try { obj = super.clone(); } catch (CloneNotSupportedException e) { } return obj; } } class Test{ public static void main(String[] args){ Point original = new Point(); Point copy = (Point)original.clone(); System.out.println(copy); } }
- covariant return type 이라고 하여, 공변 반환 타입이라고 한다.
- 이는 오버라이딩할 때 조상 메서드의 반환타입을 자손 클래스의 타입으로 변경을 허용하는 것
- 즉, Object가 아니라, Point로 반환해도 된다.
class Point implements Cloneable{ public Point clone() { Object obj = null; try { obj = super.clone(); } catch (CloneNotSupportedException e) { } return obj; } }
배열의 복사
배열도 object이기 때문에 Object로 부터 상속받았고, clone() 메서드가 있다. 따라서 다음과 같이 복사가 가능하다.
int[] arr = {1,2,3,4,5}; int[] arrClone = arr.clone();
따라서 배열 뿐만 아니라, Vector, ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, Calendar, Date와 같은 클래스들이
이와 같은 방식으로 복제가 가능하다.얕은 복사와 깊은 복사
- clone()은 단순히 객체에 저장된 값을 그대로 복제할 뿐, 객체가 참조하고 있는 객체까지 복제하지는 않는다.
- 이러한 복제를 얕은 복사라고 한다. 얕은 복사는 원본을 변경하면 복사본도 함께 영향을 받는다고 생각하면 된다.
- 반대로 원본이 참조하고 있는 객체까지 복제하는 것을 깊은 복사라고 한다.
- 깊은 복사 시에는 원본의 변경이 복사본에 영향을 미치지 않는다.
- 그래서 깊은 복사를 하기위해서는 clone을 오버라이딩하여 객체마다 new를 해주어야 한다.
String 클래스
변경 불가능한 (Immutable) 클래스
- String 클래스에는 문자열을 저장하기 위해서 문자형 배열 참조변수 char[] value를 인스턴스 변수로 정의해놓고 있다.
- 인스턴스 생성이 value에 문자열을 저장하게 되는 것이다.
- 단, 이러한 String 인스턴스가 갖고 있는 문자열은 읽어 올 수만 있고, 변경할 수는 없다.
- 가령
String a = "a"; String b = "b"; a = a+ b;
- a = a+b 인 것 같아서, 기존의 a에다가 추가하는 것 같아보이지만
- 메모리 번지 0에서 "a"가 있고, 1에서 "b" , 2에서 "ab" 가 있는 것이다.
- 따라서 결합횟수가 많아지면 메모리에 부하가 생기기 때문에 StringBuffer 클래스를 사용하는 것이 좋다.
String 생성
String은 두가지 방법으로 생성할 수 있다.
String a = "abc";
String b = new String("abc");
별 차이가 없어 보이지만, "abc" 리터럴로 생성하는 방식은 같은 메모리를 참조하는 방식이다.
String a = "abc";
String b = "abc";
이면 서로 참조하는 주소값이 같아서 a == b true가 된다.new String으로 생성하면 항상 새로 생성하기 때문에 메모리 값이 다르다.
따라서 String a = new String("abc");
String b = new String("abc");
a == b는 false가 된다.
따라서 값을 비교하고 싶다면 equals()를 사용하면 된다.
a.equals(b);
문자열 리터럴
자바 소스파일에 포함된 모든 문자열 리터럴은 컴파일 시에 클래스 파일에 저장된다.
같은 내용의 문자열 리터럴은 한 번만 저장된다. 왜냐하면 문자열 리터럴도 String 인스턴스이고, 한 번 생성하면 내용을 변경할 수 없으니 하나의 인스턴스를 공유하면 되기 때문이다.클래스 파일에는 소스파일에 포함된 모든 리터럴의 목록이 있다. 해당 클래스 파일이 클래스 로더에 의해 메모리에 올라갈 때
리터럴의 목록에 있는 리터럴들이 JVM내에 있는 상수 저장소(constant pool)에 저장된다.
빈 문자열
길이가 0인 배열이 존재할 수 있다. String = ""; 으로 선언 시에는 char 배열이 아닌 char만 들고 있는 것이다.
메서드와 생성자들
char 배열 생성자
String(char[] value) : char[] 배열을 받아서 문자열로 반환StringBuffer 생성자
String(StringBuffer) : StringBuffer를 넣어도 된다.charAt(int index) : 인덱스에 해당하는 문자 반환
compareTo(String str) : 사전순서 비교로 같으면 0 , 작으면 음수, 이후면 양수
concat(String str) : 문자열을 뒤에 덧붙인다.
contains(String) : 특정 문자열이 포함되었는 지 묻는다.
endsWith(String suffix) : 지정된 문자열로 끝나는지 검사
equalsIgnoreCase(String str) : 문자열 String 인스턴스의 문자열을 대소문자 구분없이 비교
indexOf(int ch) : 주어진 ch가 어디 인덱스에 나오는 지 확인해준다.
indexOf(int ch , int pos) : pos 이후로 ch가 어디에 있는 지 알려준다.
indexOf(String str) : 주어진 문자열이 어디에 존재하는 지 확인해준다.
intern() : 문자열을 상수풀에 등록한다.
lastIndexOf(int ch) : 맨 끝부터 찾아준다.
length() : 길이 반환
replace(char from, char to) : 문자를 새로운 문자로 바꾼 문자열을 반환
replace(String from, String to) : 문자열을 새로운 문자열로 바꾸어 준다.
split(String reg) : reg 기준으로 문자열을 분리하여 배열에 담아 반환한다.
startWith(String prefix) : prefix로 시작하는 지 확인
substring(int begin, int end) : begin 부터 end까지의 부분 문자열 반환, 단 end는 포함 x
toLowerCase() : 모든 문자를 소문자로 반환
toString() : 문자열 반환
toUpperCase() : 대문자로 반환
trim : 왼쪽, 오른쪽 끝의 공백을 제거
valueOf() : 안에 있는 값을 문자열로 변환해준다. ex) String.valueOf(100) // "100";
join
- join()은 여러 문자열 사이에 구분자를 넣어서 결합한다.
- String.join("-", arr);
StringJoiner(구분자, 맨앞, 맨뒤)
StringJoiner sj = new StringJoiner("/", "[", "]"); for(String a : arr) sj.add(s);
String.format()
- 형식화된 문자열을 만들어 반환한다.
기본형 값을 String으로 변환
- 두가지 방법이 있다.
- value+"" 방법
int i = 100; String str1 = i + "";
- valueOf();
valueOf가 약간 더 성능이 좋다는 것 외에는 별차이가 없다.int i = 100; String st2 = String.valueOf(i);
- value+"" 방법
- 두가지 방법이 있다.
- string을 다른 타입으로 변환하기
- .parseXXXX 을 사용하면 된다.
int a = Integer.parseInt(s); double d = Double.parseDouble(s); long l = Long.parseLong(s);
- 단, 양 끝에 공백 또는 문자가 있다면 예외를 낼 수 있으니 조심하도록 하자
- 부호 접미사는 허용된다.
- 단, 양 끝에 공백 또는 문자가 있다면 예외를 낼 수 있으니 조심하도록 하자
- .parseXXXX 을 사용하면 된다.
StringBuffer 클래스와 StringBuilder 클래스
- StringBuffer 클래스는 String 클래스와 달리 지정된 문자열을 변경가능하다.
- 동적으로 길이가 증가하므로 처음 생성자에서 많이 늘려주는 것이 좋다.
- 생성자와 추가
StringBuffer value = new StringBuffer("abc"); value.append("zzz").append("ssss"); // builder pattern 처럼 자신의 주소를 뱉는다.
- 기존의 설정한 크기 (default = 16)을 넘으면, 새로운 char 배열을 만들고 크기를 두 배로 잡는 과정에서 copy가 이루어지므로 조심하도록 하자
- 단 조심해야 할 것은 StringBuffer은 equals를 상속받아서 값만 비교하도록 만들지 않아서 값만 비교하려면 String으로 만든다음 비교해야 한다.
String st = value.toString(); st.equals("sa");
- 핵심 연산자
- append() : 입력으로 String이나, int 등등 여러가지 다 받는다.
- delete(int start, int end) : start부터 end사이에 있는 문자열을 제거 단, 마지막 문자는 제외
- deleteCharAt(int index) : index에 위치한 문자를 제거
- replace(int start, int end, String str) : start부터 end까지를 str로 대체한다.
- reverse() : 로꾸꺼
- setCharAt(int index, char ch) : index를 ch로 바꾼다.
- substring(int start , int end) : start부터 end(end는 포함 x)까지 가져온다.
- StringBuffer 클래스는 String 클래스와 달리 지정된 문자열을 변경가능하다.
StringBuilder
- StringBuffer는 멀티쓰레드에 안전하도록 동기화되어 있다. thread safe상태로 성능이 좋지 않다.
- 그래서, StringBuffer에서 StringBuilder가 같은 기능을 하되 thread not safe하도록 만들어서 성능을 끌어 올렸다.
wrapper 클래스
기본형은 객체가 아니다. 때문에 기본형을 객체처럼 다루는 방식이 필요할 때는 wrapper 클래스를 이용한다.
종류
- Boolean
- Character
- Byte
- Short
- Integer
- Long
- Float
- Double
이들은 equals가 오버라이딩 되어있어 값에 따른 동등비교 사용이 가능하다.
다만 비교연산자는 ``없어서 compareTo를 사용해야 한다.
Number 클래스
- Number 클래스의 자손으로 Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal 등이 있다.
- Boolean, Character 등은 따로 있다.
- Number 클래스의 자손으로 Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal 등이 있다.
오토박싱과 언박싱
- jdk 1.5이전에는 기본형과 참조형 간의 연산이 불가능했다.
- 즉, wrapper 클래스로 기본형을 객체로 만들어서 연산해야 했다.
- 그러나 이제는 기본형과 참조형 간의 덧셈이 가능하다.
- 컴파일러가 자동으로 변환해주는데 intValue() 를 추가해주기 때문이다.
- 이외에도 Vector클래스나 ArrayList클래스에 기본형 값을 저장할 때나 형변환이 필요할 때도 컴파일러나 자동적으로 코드를 추가해준다.
- 기본형 값을 래퍼 클래스 객체로 자동 변환 : 오토박싱
- 반대로 객체 클래스를 기본형 값으로 변환하는게 : 언박싱이다.
'노답 스터디 > JAVA' 카테고리의 다른 글
Java 문법 정리 10일차 - inner class (0) | 2021.07.11 |
---|---|
Java 문법 정리 9일차 - interface (0) | 2021.07.11 |
Java 문법 정리 8일차 - 다형성 (0) | 2021.07.11 |
Java 문법 정리 7일차 - 추상 메서드 (0) | 2021.07.11 |
Java 문법 정리 6일차 - 제어자 (0) | 2021.07.11 |