java.lang 패키지는 자바 프로그의 기본적인 클래스를 담고 있는 패키지로 import 없이 사용이 가능하다.
java.lang 패키지에 속하는 주요 클래스와 클래스의 용도를 간단하게 살펴보면 다음과 같다.
이외에도 자바에서 제공하는 API는 매우 다양하기 때문에 API 도큐먼트를 찾아보고, 어떤 기능을 제공하는지 이해하도록 하자.
< 자바 API 도큐먼트 >
API는 라이브러리(library)라고 부르기도 하며, 프로그램 개발에 자주 사용되는 클래스 및 인터페이스의 모음을 말한다.
즉, 그동안 사용해왔던 String 클래스와 System 클래스도 모두 API에 속하는 클래스이다.
API 도큐먼트는 방대한 자바 표준 API 중에서 원하는 API를 쉽게 찾아 이용할 수 있도록 도와주며 HTML 페이지로 작성되어있다.
아래의 URL을 통해 확인해보자.
https://docs.oracle.com/en/java/javase/index.html
이클립스에서도 API 도큐먼트를 볼 수 있으며 방법은 다음과 같다.
1. 코드 편집 뷰에서 String 클래스에 마우스 위치
2. F1키 누르기
< Object 클래스 >
클래스 선언 시 extends 키워드로 다른 클래스를 상속하지 않더라도 암시적으로 java.lang.Object 클래스를 상속한다.
따라서 자바의 모든 클래스는 Object 클래스의 자식이거나 자손 클래스이다.
즉, Object 클래스는 자바의 최상위 부모 클래스에 해당한다.
API 도큐먼트에서 Object 클래스를 살펴보면 Object 클래스는 필드가 없고, 생성자와 메소드로 구성되어 있다.
모든 클래스의 최상위 부모가 Object이므로 모든 클래스에서 Object의 메소드를 사용할 수 있다.
▶ 객체 비교(equals( ))
Object 클래스에는 객체 비교를 할 수 있는 equals( ) 메소드가 존재한다.
public boolean equals(Object obj) {...}
equals( ) 메소드의 매개 타입은 Object인데, 이는 모든 객체가 매개값으로 대입될 수있음을 말한다.
equals( ) 메소드는 비교 연산자인 ==과 동일한 결과를 리턴한다. 즉, 동일한 객체라면 true, 아니라면 false를 리턴한다.
이는 논리적으로 동등하다는 의미로 같은 객체든 다른 객체든 상관없이 객체가 저장하고 있는 데이터가 동일함을 뜻한다.
예를 들어 String 객체의 equals( )메소드는 객체의 번지가 아닌 문자열을 비교하여 같다면 true를 리턴하고 그렇지 않다면 false를 리턴한다.
그 이유는 String 클래스에서 Object의 equals( ) 메소드를 재정의(오버라이딩)해서 번지 비교가 아닌 문자열 비교로 변경하기 때문이다.
이처럼 equals( )메소드는 직접 사용되지 않고 하위 클래스에서 재정의하여 논리적으로 동등 비교로 사용된다.
equals( ) 메소드를 재정의할 때에는 매개값이 기준 객체와 동일한 타입의 객체인지 먼저 확인해야 하며, 이는 instanceof 연산자로 이루어진다.
아래 예제는 객체 동등 비교 예시이며, 이를 위해 Member 클래스에서 equals( )메소드를 재정의하여 사용하였다.
//Member 클래스
public class Member {
public String id;
public Member(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
//매개값이 Member타입인지 확인
if(obj instanceof Member) {
// Member타입으로 강제 타입 변환 후 id 필드값이 동일한지 검사,동일하다면 true 리턴
Member member = (Member) obj;
if(id.equals(member.id)) {
return true;
}
}
// 매개값이 Member타입이 아니거나 id필드값이 다른경우 false 리턴
return false;
}
}
//Member객체 사용
public class MemberExample {
public static void main(String[] args) {
Member obj1 = new Member("blue");
Member obj2 = new Member("blue");
Member obj3 = new Member("red");
// 매개값이 Member타입이고 id 필드값도 동일하므로 true
if(obj1.equals(obj2)) {
System.out.println("obj1과 obj2는 동등합니다.");
} else {
System.out.println("obj1과 obj2는 동등하지 않습니다.");
}
// 매개값이 Member타입이지만 id필드값이 다르므로 false
if(obj1.equals(obj3)) {
System.out.println("obj1과 obj3은 동등합니다.");
} else {
System.out.println("obj1과 obj3은 동등하지 않습니다.");
}
}
}
결과 :
▶ 객체 해시코드(hashCode( ))
객체 해시코드란 객체를 식별하는 하나의 정수 값을 말한다.
Object 클래스의 hashCode( ) 메소드는 객체의 메모리 번지를 이용해서 해시코드를 만들어 리턴하기 때문에 객체마다 다른 값을 가지고 있다.
이러한 이유 때문에 논리적 동등 비교시 hashCode( )를 오버라이딩할 필요가 있다.
(HashSet, HashMap, Hashtable과 같은 방법을 통해 동등한 객체인지 비교가 가능하며 각 방법들에 대한 자세한 내용은 뒤에서 다루도록 하자.)
먼저 hashCode( ) 메소드를 실행해서 리턴된 해시코드 값이 같은지를 확인한다.
만약 해시코드 값이 다르다면 다른 객체로 판단하고, 해시코드 값이 같으면 equals( )메소드로 다시 비교한다.
때문에 hashCode( ) 메소드가 true를 리턴해도 equals( )의 리턴값이 다르면 다른 객체가 된다.
아래 예제는 hashCode( ) 메소드 재정의 유무에 따른 결과 차이를 보여준다.
1. hashCode( ) 메소드 재정의 X
public class Key {
public int number;
public Key(int number) {
this.number = number;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key) obj;
if(this.number == compareKey.number) {
return true;
}
}
return false;
}
}
import java.util.HashMap;
public class KeyExample {
public static void main(String[] args) {
//Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성
HashMap<Key, String> hashMap = new HashMap<Key, String>();
//식별키 "new Key(1)" 로 "홍길동"을 저장함
hashMap.put(new Key(1), "홍길동");
//식별키 "new Key(1)" 로 "홍길동"을 읽어옴
String value = hashMap.get(new Key(1));
System.out.println(value);
}
}
결과 :
다음의 경우 식별키로 Key 객체를 사용하면 저장된 값을 찾아오지 못한다.
그 이유는 number 필드값이 같더라도 hashCode( ) 메소드에서 리턴하는 해시코드가 다르므로 다른 식별키로 인식하기 때문이다.
1. hashCode( ) 메소드 재정의 O
public class Key {
public int number;
public Key(int number) {
this.number = number;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key) obj;
if(this.number == compareKey.number) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
return number;
}
}
import java.util.HashMap;
public class KeyExample {
public static void main(String[] args) {
//Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성
HashMap<Key, String> hashMap = new HashMap<Key, String>();
//식별키 "new Key(1)" 로 "홍길동"을 저장함
hashMap.put(new Key(1), "홍길동");
//식별키 "new Key(1)" 로 "홍길동"을 읽어옴
String value = hashMap.get(new Key(1));
System.out.println(value);
}
}
결과 :
id 필드값이 같을 경우 같은 해시코드를 리턴하도록 String의 hashCode( ) 메소드를 재정의하였다.
그 결과 홍길동이 출력되는 것을 확인할 수 있다.
▶ 객체 문자 정보(toString( ))
Object 클래스의 toString( ) 메소드는 객체의 문자 정보를 리턴한다.
객체의 문자 정보란 객체를 문자열로 표현한 값을 말하며 기본적으로 '클래스이름@16진수해시코드'로 구성되어 있다.
우리가 실제로 사용할 때에는 Object의 toString( )메소드의 리턴값은 별 값어치가 없는 정보이기 때문에 하위 클래스에서 toString( ) 메소드를 재정의(오버라이딩)하여 간결하고 유익한 정보를 리턴하도록 되어있다.
예를 들어, Date 클래스는 toString( )메소드를 사용하여 현재 시스템의 날짜와 시간 정보를 리턴하며, String 클래스에서는 toString( ) 메소드를 사용하여 저장하고 있는 문자열을 리턴한다.
또한 System.out.println( ) 메소드는 매개 값이 객체라면 객체의 toString( ) 메소드를 호출하여 리턴값을 출력하도록 되어있다.
< System 클래스 >
자바 프로그램은 운영체제에서 바로 실행되는 것이 아닌 JVM위에서 실행되기 대문에 운영체제의 모든 기능을 직접 이용하기는 어렵다.
하지만 System 클래스를 이용하면 운영체제의 일부 기능을 이용할 수 있다.
System 클래스의 모든 필드와 메소드는 정적 필드와 정적 메소드로 구성되어 있음을 알아두자.
▶ 프로그램 종료(exit( ))
경우에 따라서 강제적으로 JVM을 종료시켜야 할 때가 있으며 이럴 경우 exit( ) 메소드를 호출해서 사용한다.
exit( ) 메소드는 현재 실행하고 있는 프로세스를 강제 종료시키는 역할을 한다.
exit( ) 메소드는 int 매개값을 지정하도록 되어 있는데, 이 값을 종료 상태값이라고 한다.
일반적으로 정상 종료일 경우 0값을 준다.
System.exit(0);
▶ 현재 시각 읽기(currentTimeMillis( ), nanoTime( ))
System 클래스의 currentTimeMillis( ) 메소드와 nanoTime( )메소드는 컴퓨터의 시계로부터 현재 시간을 읽어서 밀리세컨드(1/1000초) 단위와 나노세컨드(1/1000000000초) 단위의 long 값을 리턴한다.
long time = System.currentTimeMillis();
long time = System.nanoTime();
'프로그래밍언어 > Java' 카테고리의 다른 글
11-2 java.util 패키지 (0) | 2022.03.03 |
---|---|
11-1 java.lang 패키지(2) (0) | 2022.03.02 |
10-2 예외 처리 (0) | 2021.12.27 |
10-1 예외 클래스 (0) | 2021.12.27 |
09-2 익명 객체 (0) | 2021.12.14 |