JavaStudy Chap. 9
Java의 정석 챕터9 java.lang 패키지 & 유용한 클래스
- java.lang 패키지
가장 기본이 되는 클래스를 포함하고 있으며 import 없이도 사용할 수 있다.
- Object 클래스
모든 클래스의 최고조상이므로 Object의 메소드들은 모든 클래스에서 바로 사용가능
1. equals()
public boolean equals(Object obj)
/*실제내용
public boolean equals(Object obj) {
return (this==obj);
} */
객체의 참조변수(저장된 주소값)를 비교해 같고 다름을 판단한다
따라서 이것만으로 인스턴스의 값들(객체에 저장된 내용)을 비교하는 것은 불가능하다.
객체의 내용을 비교하려면 해당 클래스에서 equals메소드를 오버라이딩 해서 수정하면 된다.
class Person { long id; public boolean equals(Object obj) { //직접 멤버변수 비교해서 리턴하도록 오버라이딩 if(obj instanceof Person) return id==((Person)obj.)id; else return false; } }
실제로 String간의 equals도 참조변수가 아닌 인스턴스 내용을 비교하도록 오버라이딩 되어 있다.
2. hashCode()
public int hashCode()
객체의 주소값을 해시코드로 만들어 반환한다
String 클래스에서는 문자열의 내용이 같으면 동일한 해시코드를 반환하도록 hashCode를 오버라이딩 했다.
String str1 = new String("abc");
System.out.println(str1.hashCode()); //-> 주소 해시코드 리턴
3. toString()
public String toString()
/*
실제로 정의된 내용
public String toString() {
return getClass().getName()+"@"+Integer.toHexString(hashCode());
*/
인스턴스의 정보를 문자열로 제공한다
따로 오버라이딩 하지 않고 Object에 정의된 내용대로 사용한다면
"클래스이름+16진수의 해시코드"를 얻게 된다.
- String클래스에서의 toString()
: 인스턴스가 가진 문자열을 반환하도록 오버라이딩 되어있다.
- 일반적으로 인스턴스, 클래스에 대한 정보나 인스턴수 변수의 값을 문자열로 반환하도록 오버라이딩 하는 것이 보통이다.
: Object에서의 접근제어자가 public이므로
이를 오버라이딩 할 때는 접근제어자를 public으로 해야한다.class Card { String kind; int number; Card(String kind, int number) { this.kind = kind; this.number=number; } public toString() { //인스턴스 정보 리턴하도록 오버라이딩 return "kind : "+kind+", number : " + number; }
4. clone()
protected Object clone()
자신을 복제해 새 인스턴스를 생성한다.
Object의 clone의 경우 단순 인스턴스변수의 값만 복사하기 때문에
참조타입 인스턴스변수를 가진 경우에는 완전한 복제x
이런 경우에는 새 인스턴스를 생성하고, 내용을 복사하도록
오버라이딩 해야 함.
- 복제할 클래스가 Cloneable 인터페이스를 구현해야 한다
: 데이터 보호목적 : 인터페이스가 구현되어 있다 = 복제를 허용한다- 접근제어자 public으로 사용
: 상속관계 없는 다른 클래스에서도 호출- 조상클래스의 clone을 호출
:super.clone();
class Point implements Cloneable { //Cloneable 구현 ... public Object clone() { //public으로 설정 Object obj = null; try { super.clone(); //try-catch안에서 조상의 clone 호출 } catch (CloneNotSupportedException e) {} return obj; } }
- clone을 오버라이딩 해둔 클래스들
: 배열, Vector, ArrayList, LinkedList, HashSet, Date, ... 등 클래스는
clone()을 이용해 간단하게 복사할 수 있도록 오버라이딩 되어 있다.
int[] arr = {1,2,3,4};
int[] arrClone = arr.clone();
//완전히 같음
int[] arrClone = new int[arr.length];
System.arrayCopy(arr,0,arrClone,0,arr.length);
얕은복사, 깊은복사
clone()은 객체가 참조하는 객체까지 복사하지는 못하는 얕은 복사를 수행한다.
따라서 객체배열을 복사하는 경우, 원본과 복사본이 같은 객체를 공유하게 된다.깊은복사를 하는 방식 예제
원본이 가지고 있는 참조변수의객체까지 새로 만들어서 복제한다.class Circle implements Cloneable { Point p; //다른 객체의 참조변수를 멤버로 가지고 있음 double r; public Circle deepCopy() { Object obj = null; try { obj = supler.clone(); } catch (CloneNotSupportedException e) {} //참조변수의 객체까지 새로 복제!! Circle c = (Circle)obj; c.p = new Point(this.p.x, this.p.y); } }
5. getClass()
public class getClass()
자신이 속한 클래스의 Class 객체를 반환한다.
Class 클래스
- 클래스의 모든 정보를 담고있다. 클래스 당 1개만 존재
- 클래스 파일이 메모리에 올라갈 때 자동으로 생성됨
- 클래스 로더가 파일형태로 저장되어 있는 클래스를 읽어서 Class클래스에 저장되어 있는 형식으로 변환한다. (클래스 객체의 참조를 반환하거나 클래스패스에 지정된 경로를 따라 클래스 파일을 찾음): 즉 클래스 파일을 읽어서 사용하기 편한 형태로 저장해 놓은 것이 클래스객체이다.
- Class 객체를 얻는 방법
클래스 정보를 얻기위해서는 먼저 Class객체의 참조를 얻어야 한다
-
생성된 객체로부터 얻는 방법 : getClass()
Class obj = new Card().getClass();
-
클래스 리터럴로부터 얻는 방법 : *.class
Class obj = Card.class;
-
클래스 이름으로부터 얻는 방법 : Class.forName()
Class obj = Class.forName("Card");
String 클래스
String 클래스에서는
char배열 참조변수 인스턴스변수로 문자열을 저장한다.
- immutable class
: 한 번 생성된 문자열인스턴스는 값을 변경할 수 없다.
'+'연산자로 결합하는 경우에도 값이 바뀌는 것이 아니라 새 String 인스턴스를 생성하는 것이다.
- String 리터럴
소스파일에 포함된 모든 문자열리터럴은 컴파일 시에 클래스파일에 저장된다.
-> 해당 클래스파일이 메모리에 올라갈 때
소스파일에 존재하는 리터럴목록은 JVM내의 상수저장소에 저장된다.
※즉, 소스파일마다 포함되어 있는
모든 문자열리터럴에 대한 인스턴스를 각각 한 개만 생성해둔다!
: 하나의 인스턴스를 생성해두고 공유하면 되기때문
String s1 = "aa"; String s2 = "aa"; String s3 = "aa";
=> s1,s2,s3는 모두 하나의 "aa"인스턴스를 참조하게 된다.
-String의 비교
String 객체를 생성하는 방법 두 가지
- 문자열리터럴을 지정
String str1 = "abc"; String str2 = "abc";
- String의 생성자를 사용해 생성
String str3 = new String("abc"); String str4 = new String("abc");
- 비교방식의 차이
- equals()를 사용하면 인스턴스의 값을 비교하기 때문에 전부 true를 반환한다.
- String 인스턴스의 주소를 등가비교하는 경우,
리터럴을 지정했을 때는 같은 주소를 공유하므로 true지만
각각 다른 인스턴스를 생성했을 경우에는 falsue를 반환한다.
-String 생성자, 메소드
책 469p. ~ 471p. 참조
- String 결합, 분리 : join(), split()
- split
String[] split(String regex)
지정된 분리자로 String을 분리해서 String 배열로 반환한다.
String animals ="cat,dog";
String[] arr = animals.split(",);
//-> arr는 ["cat","dog"]
- join
String join(String regex, String[] arr)
배열의 문자열들을 구분자로 연결해서 하나의 String으로 반환
String animals = String.join("-",arr);
//=> animals는 "cat-dog"
기본형<->String 변환
- 기본형 -> String
- 기본형에 빈문자열 "" 붙여주기
String str1 = 100 + "";
- valueOf() 사용
String str2 = String.valueOf(100);
- String -> 기본형
- valueOf() 사용
int i = Integer.valueOf("100");
: 사실 함수이름을 통일하기 위함이고, 내부적으로는 parse와 완전 동일- parseInt() 사용
Boolean.parseBoolean(String s) Integer.paseInteger(String s) Double.parseDouble(String s) ...
- String -> 숫자 변환에서 예외가능성
- 문자열에 공백, 문자가 포함된 경우 예외(NumberFormatException) 발생
: 문자열 양 끝의 공백을 없애는 trim()을 같이 사용하기도 함- 자료형이 맞는 경우, 부호('+', '-')와 소수점('.'), 자료형접미사는 허용된다.
StringBuffer클래스
StringBuffer는 내부적으로 문자열편집을 위한 버퍼를 가지고있어
지정된 문자열을 변경할 수 있다.
StringBuffer도 String 클래스와 유사하게 char형배열에 문자열을 저장한다
버퍼의 크기는 인스턴스를 생성할 때 지정한다.
- StringBuffer 생성자
public StringBuffer(int length)
를 사용해 버퍼의 적절한 크기를 지정해주는 것이 좋다.
(기본생성자는 16크기의 버퍼를 생성한다.)
- StringBuffer 변경
StringBuffer 인스턴스를 변경하는 메소드들은
반환타입이 객체 자신인 경우가 많다.
-> 자기 자신의 주소를 반환하므로 변경메소드의 하다.
StringBuffer sb = new StringBuffer("abc"); String Buffer sb1 = sb.append("123"); //->sb와 같은 문자열을 참조 sb1.append("456").append("efg"); //-> sb와 sb1는 같은 문자열 "abc123456efg"를 참조한다
- StringBuffer의 비교
StringBuffer는 String과 다르게 equals()를 오버라이딩 하지않아
equals()만으로 인스턴스 내용을 비교할 수 없다
하지만 StringBuffer는 toString()을 오버라이딩 하고있으므로
- toString()으로 String 인스턴스 얻기
- equals()로 비교
의 과정을 거쳐야 한다.//StringBuffer sb와 sb2 비교 String s = sb.toString(); String s2 = sb2.toString(); System.out.println(s.equals(s2)); //->true
-StringBuffer생성자, 메소드
책 480p. ~ 481p. 참고
String 클래스와 유사하며 내용변경을 위한 메소드들이 추가로 제공된다.
- 맨 뒤에 삽입 :
StringBuffer append(타입 변수)
- 지정 위치에 삽입 :
StringBuffer insert(int pos, 타입 변수)
- 문자열 뒤집기 :
StringBuffer reverse()
- 특정위치의 문자열 제거 :
StringBuffer delete(int start, int end)
...
- StringBuilder
StringBuffer에서 쓰레드의 동기화만 뺀 버전, 완전히 똑같은 기능으로 작성되어 있으므로 이름만 바꾸면 변경 가능하다.
wrapper 클래스
기본형 값들을 객체로 다루기 위해 사용하는 클래스
전부 equals()가 오버라이딩 되어 있으므로 eqauls()로 값비교가 가능하다
또한 toString()도 사용 가능하며
static 상수( MAX_VALUE, MIN_VALUE, SIZE, TYPE, ...)을 저장하고있다.
- Number 클래스
추상클래스로, 숫자를갖는 래퍼클래스의 조상이다
(Byte, Short, Integer, Long, Float, Double, BigInteger, BigDecimal)
객체가 가지고 있는 값을 기본형으로 반환하는 메소드들을 정의하고 있다.
- 문자열 -> 숫자 변환
위에서 봤던 방법 중 valueOf()의 반환형은 래퍼클래스이다.
하지만 오토박스 기능 덕분에 parse타입 메소드와 큰 차이가 없어졌다
- 오토박싱, 언박싱
- 오토박싱 : 기본형값 -> 래퍼클래스 객체로 자동변환
- 언박싱 : 래퍼클래스 -> 기본형값 자동변환
: 컴파일러가 자동으로 변환 메소드를 추가해주기 때문
- Vector, ArrayList에서의 유용성
: 내부적으로 객체배열을 갖는 클래스에서 기본형 값을 저장할 때 자동으로 형변환을 해주므로 편리함
유용한 클래스
- java.util.Objects
객체의 비교, 널체크에 활용
널체크
1.static boolean inNull(Object obj)
: 객체가 null이면 true 반환
2.static boolean nonNull(Object obj)
: null이 아니면 true 반환
3.requireNonNull()
: null이면 NullPointerException을 발생시킴 : 유효성검사구문 단순화
객체의 대소비교
static int compare(Object a, Object b, Comparator c)
=> 같으면 0, 크면 양수, 작으면 음수 반환
객체의 재귀적 비교 : 다차원배열의 비교가 가능해짐
static boolean deepEquals(Object a, Object b)
- java.util.Random
난수를 생성하는 방법 중, Math클래스의 random도 내부적으로 Random클래스의 인스턴스를 생성해 사용하므로 동일하다.
차이점은 Random클래스에서는 종자값을 직접 설정할 수 있다는 점이다
: 같은 종자값을 갖는 Random인스턴스는 같은 값을 같은 순서로 반환하는 것을 보장한다.
기본생성자 Random()은 종자값을 System.currentTimeMillis() (현재시간변환)을 사용하기 때문에 실행할 때마다 난수를 다르게 얻는다.
범위의 랜덤값을 반환하는 메소드
nextInt(int n)
- java.util.Scanner
- 다양한 입력소스로부터 문자데이터 읽어오는데 활용
//생성자들 Scanner(String source) Scanner(File source) Scanner(InputStream source) Scanner(Path source) //...
- 복잡한 형태의 구분자 처리, 정규식 활용
Scanner useDelimiter(Pattern pattern) Scanner useDelimiter(String pattern) //...
next타입()
메소드로 화면으로부터 라인단위로 입력받아
정규식 활용해 형식에 맞게 문자열을 입력받는 방식으로 사용
Scanner s = new Scanner(System.in); //객체생성
String argArr = null; //구분자로 잘라서 저장위한 배열
while(true) {
String input = s.nextLine(); //라인단위 입력
input = input.trim() //공백제거
argArr = input.split(" +"); //구분자로 자름
String command = argArr[0].trim();
if("".equals(command)) continue;
if(command.equals('q')) System.exit(0);
else {
for (int i=0;i<arrArr.length;i++)
System.out.println(argArr[i];)
}
}
}
Author And Source
이 문제에 관하여(JavaStudy Chap. 9), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@quokka_beam/JavaStudy-Chap.-9저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)