여기서 lang은 langauge의 줄임말로, 이 패키지는 자바언어를 이루는 가장 기본 클래스들을 보관하는 패키지를 말한다.
이 패키지는 자바 애플리케이션 단에서 자동으로 import 되어서 생략 가능하다.
java.lang 의 대표 클래스들
모든 클래스의 최상위 부모 클래스는 Object 클래스이다.
모든 Java 클래스는 Object를 직접 또는 간접적으로 상속하므로, Object 타입 변수는 모든 클래스의 객체를 참조할 수 있다.
class B { // Object 상속받음(직접 상속)
}
class A extends B { // Object를 상속받은 B를 상속받음(간접 상속)
}
Object를 활용한 다형성의 한계
Object 타입은 모든 객체를 다형적으로 참조할 수 있다. 오버라이딩된 Object 메서드는 실제 객체의 메서드가 실행되지만, 참조 타입이 Object이므로 각 클래스에만 정의된 고유 메서드를 호출하려면 다운캐스팅이 필요하다.
class Dog {
void bark() {
System.out.println("멍멍");
}
@Override
public String toString() {
return "강아지";
}
}
Object obj = new Dog();
System.out.println(obj.toString()); // Dog에서 오버라이딩한 메서드 실행
// obj.bark(); // 컴파일 오류: Object에는 bark()가 없음
-> 공통으로 사용할 수 있는 메서드가 적어 다형성 활용에 한계가 있다.
Object 배열을 만들면 모든 객체를 담을 수 있는 배열이 만들어 진다.
Object obj[0] = new Cat();
Object obj[1] = new Dog();
Object obj[2] = new Lion();
Object.toString() 메서드는 객체의 정보를 문자열 형태로 제공한다.
모든 클래스에서 상속받아 사용 가능하다.
public String toString() {
return getClass().getName()
+ "@"
+ Integer.toHexString(hashCode());
}
System.out.println() 메서드는 내부에서 String.valueOf()를 거쳐 toString()을 호출한다.
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
객체의 정보를 원하는 방식으로 제공하고 싶으면 toString()을 오버라이딩해서 사용
만약 Object 클래스가 없다면 클래스마다 toString 메서드를 정의해 작성해야 한다.
사용하는 클래스가 특정 구현 클래스를 직접 참조하므로, 구현 클래스를 다른 것으로 교체할 때 사용하는 코드도 수정해야 한다.
사용하는 클래스가 여러 구현 클래스의 공통 상위 타입인 인터페이스나 추상 클래스에 의존하므로, 구현체가 바뀌어도 사용하는 코드는 수정하지 않아도 된다.
확장에는 열려 있고, 변경에는 닫혀 있어야 한다.
Object는 동등성 비교를 위한 equals() 메서드는 제공한다.
== 연산자를 사용해서 두 객체가 참조가 동일한 객체를 가리키고 있는지 확인
equals() 메서드를 사용하여 두 객체가 논리적으로 동등한지 확인
public boolean equals(Object obj) {
return (this == obj);
}
같은 hashCode()를 가진다고 해서 반드시 equals()가 true인 것은 아니다.