2020. 5. 27. 20:46ㆍ프로그래밍/Java
java.lang패키지
java.lang패키지는 자바프로그래밍에 가장 기본이 된느 클래스들을 포합하고 있습니다 그렇기 때문에 java.lang패키지의 클래스들은 import문 없이도 사용할 수 있게 되어 있습니다 그동안 String클래스나 System클래스를 import문 없이 사용할 수 있었던 이유가 바로 java.lang패키지에 속한 클래스들이기 때문이었던 것 입니다 . 우선javav.lang패키지의 여러 클래스들중에서도 자주 사용되는 클래스 몇가지만을 골라서 학습해봅니다.
Object클래스
클래스의 상속을 배울때 Object클래스에 대해 이미 배웠지만 여기서는 전에 배운것에 추가로 설명하겠습니다.
Object클래스는 모든 클래스의 최고 조상이기때문에 Object클래스의 멤버들은 모든 클래스에서 바로 사용이 가능합니다.
Object클래스의 메서드 | 설 명 |
protected Object clone() | 객체 자신의 복사분을 반환합니다 |
public boolean equals(Object obj) | 객체자신과 객체obj가 같은 객치인지 알려줍니다(같으면 true) |
protected void finalize() | 객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출됩니다 이때 수행되어야 하는 코드가 있을 때 오버 라이딩합니다(거의 사용하지는 않습니다) |
public class getClass() | 객체 자신의 클래스 정보를 담고 있는 Class인스턴스를 반환합니다 |
public int hashCode() | 객체 자신의 해시 코드를 반환 합니다 |
public String toString | 객체 자신의 정보를 문자열로 반환합니다 |
이 메서드들은 모든 인스턴스가 가져야할 기본적인 것들이며 우선 이중에서 중ㅇ한 몇가지만 살펴봅니다.
equals(Object obj)
매개변수로 객체의 참조변수를 받아서 비교하여 그 결과를 boolean값으로 알려주는 역할을 합니다 아래의 코드는 Object클래스에 정의되어있는 equals메서드의 실제 내용입니다
public boolean equals(Object obj){
return(this == obj);
}
위의 코드에서 알 수 있듯이 두 객체의 같고 다름을 참조변수의 값으로 판단합니다 그렇기 때문에 서로 다른 두 객체를 equals메서드로 비교하면 항상 false를 결과로 얻게 됩니다 Object클래스로부터 상속 받은 equals메서드는 결국 두개의 참조변수가 같은 객체를 참조하고있는지 즉 두 참조변수에 저장된 값 이 같으지 판단하는 기능밖에 할수 없습니다
toString()
이메서드는 인스턴스 에 대한 정보를 문자열로 제공할 목적으로 정의한 것입니다 인스턴스 의 정보를 제공한다는 것은 대부분의 경우 인스턴스 변수에 저장된 값들을 문자열로 표현한다는 뜻입니다.
package day01;
class Card{
String kind;
int number;
Card(){
this("SPADE",1);
}
Card(String kind, int number){
this.kind;
this.number = number;
}
}
public class Ex01 {
public static void main(String[] args) {
Card c1 = new Card();
Card c2 = new Card();
System.out.println(c1.toString());
System.out.println(c2.toString());
}
}
Card인스턴스 두개를 생성한 다음 각 인스턴스에 toString()을 호출한 결과를 출력했습니다 Card 클래스에서 Object클래스로부터 상속받은 toString 을 오버라이딩 하지 않았지떄문에 Card인스턴스에 toString()호출하면 Object클래스의 toString()이 호출이 됩니다 서로 다른 인스턴스에 대해서 toString()을 호출하였으므로 클래스의 이름은 같아도 해시코드 값이 다르다는것을 확인 할수 있습니다.
package javatest;
public class ToStringTest {
public static void main(String[] args) {
String str = new String("KOREA");
java.util.Date today = new java.util.Date();
System.out.println(str);
System.out.println(str.toString());
System.out.println(today);
System.out.println(today.toString());
}
}
위의 결과에서 알수 있듯이 String 클래스와 Date 클래스의 toString()을 호출하였더니 클래스이름과 해시코드 대신 다른 결과가 출력됩니다
String클래스의 toString()은 String인스턴스가 갖고 있는 문자열을 반환하도록 오버라이디 되어 있고Date클래스의 경우Date인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하여 반환하도록 오버 라이디 되어있습니다.
이처럼 toString()은 일반적으로 인스턴스나 클래스에 대한 정보 또는 인스턴스 변수들의 값을 문자열로 변환하여 변환하도록 오버라이딩 되는것이 보통입니다.
clone()
이 메서드는 자신을 복제항 새로운 인스턴스를 생성하는 잉을 합니다 어떤 인스턴스에대해 작업을 할때 원래의 인스턴스는 보존하고 clone메서드를 이용하여 새로운 인스턴스를 생성하여 작을을 하면 작업이전의 값이 보존되므로 작업에 실패해서 원래의 상태로 되돌리거나 변경되기전의 값을 참고하는데 도움이 될것입니다.
Object클래스에 정의된 clone()은단순히 인스턴스 변수의 값만을 복사하기떄문에 참조타입의 인스턴스 변수가 있는 클래스는 완전한 인스턴스 복제가 이루어지지않습니다.
예를들어 배열의 경우 복제된 인스턴스에 영향을 미치게 되며 이런경우 clone메서드를 오버라이딩하여 새로운 배영을 생성하고 배열의 내용을 복사해야합니다
얕은복사와 깊은 복사
clone()은 단순히 객체에 저장된 값을 그대로 복제할뿐 객체가 참조하고 있는 객체까지 복제 하지는 않습니다 기본형 배열인 경우에는 아무런 문젝 없지만 객체배열을 clone()으로 복제하는경우에는 원본가 복제본이 같은 겍체를 공유하므로 완전한 복제라고 보기는 어렵습니다 이러한 복제를 얕은 복사라 하며 얕은복사에서는 원본을 변경하면 복사본도 영향을 받습니다.
반면에 원본이 참조하고있는 객체까지 복제하는것을 깊은 복사라고 하며 깊은 복사에서는 원본과 복사본이 서로 다른 객체를 참조하기때문에 원본의 변경이 복사본에 영향을 미치지 않습니다 예를들어 컴퓨터에서 바로가기 는 얕은복사 복제된 파일를 깊은 복사라고 생각하시면 편합니다.
getClass()
이 메서드는 자신이 속한 크랠스의 Class객체를 반환하는 메서드 인데 Class객체는이름이 'Class'인클래스의객체입니다 Class클래스는아래와같이정의합니다.
public final class Class implements ...{// Class클래스
...
}
Class객체는 클래스의모든 정보를 담고 있으며 클래스당 1개만 존재하며 클래스파일이 클래스로더에 의해서메모리에 올라갈때 자동으로 생성됩니다 클래스 로더는 실행시 필요한 클래스를 동적으로 메모리에 로드하는 역할을 합니다 먼저 기존에 생성된 클래스가 메모리에 존재하는지 확인하고 있으면 객체의 참조를 반환하고 없으면 클래스 패스에 지정된 경로를 따라서 클래스 파일을 찾습니다
못찾으면 ClassNotFoundException이 발생하고 찾으면 해당 클래스 파일을 읽어서 Class객체로 변환합니다.
그르므로 파일 형태로 저장되어 있는 클래스를 읽어서 Class클래스에 정의된 형식으로 변환하는 것입니다 즉 클래스 파일을 읽어 사용하기 편한형태로 저장해놓은것이 클래스 객체입니다.
클래스의 정보가 필요할때 먼저 Class객체에 대한 참조를 얻어 와야하는데 해당 Class객체에 대한 참조를 얻는 방법은 여러가지가 있습니다
Class cObj = new Card().getClass();//생성된 객체로부터 얻는방법
Class cObj = Card.class;//클래스 리터럴(*.class)로 얻는 방법
Class cObj = Class.forName("Card")//클래스 이름으로 얻는방법
특히 forName()은 특정 클래스 파일 예를 들어 데이터베이스 드라이버를 메모리에 올릴떄 주로 사용합니다
Class 객체를 이용하면 클래스에 정의된 멤버의 이름이나 개수등 클래스에 대한 모든 정보를 얻을수 있기 떄문에 Class객체를 통해서 객체를 생성하고 메서드를 호출하는등 보다 동적인 코드를 작서할수 있습니다
Card c = new Card();//new연산자를 이용해서 객체생성
Card c = Card.class.newInstance()//Class객체를 이용해서 객체생성
동적으로 객체를 생성하고 메서드를 호출하는 방법에 대해 더 알고싶다면 리플렉션API로 검색하면됩니다.
'프로그래밍 > Java' 카테고리의 다른 글
ArrayList와 LinkedList (0) | 2020.06.01 |
---|---|
내부클래스 (0) | 2020.05.29 |
다형성 (0) | 2020.05.26 |
추상클래스와 인터페이스 (0) | 2020.05.25 |
예외처리 (0) | 2020.05.22 |