Java 파트11-1. java.lang 패키지
1. 시작하기 전에
- java.lang 패키지는 자바 프로그램의 기본적인 클래스를 담은 패키지이다.
- java.lang 패키지의 클래스와 인터페이스는 import 없이 사용할 수 있다.
2. 자바 API
- 프로그램 개발에 자주 사용되는 자바에서 제공하는 클래스 및 인터페이스 모음
- 자바 라이브러리라고도 함
- API 도큐먼트를 통해 사용방법을 확인할 수 있다.
- 이클립스에서 클래스 드래그 후 F1키 클릭 - HELP 뷰로 이동 - java.lang.클래스 링크 클릭하면 바로 API 도큐먼트 확인 가능
자바 API 도큐먼트 링크
API 도큐먼트에서 클래스 페이지 읽는 방법
최상단 SUMMARY:NESTED | FIELD | CONSTR | METHOD
클릭했을 때 바로가기가 이동하지 않는다면 없는 것이다.
- SUMMARY : 클래스 내 선언된 멤버가 어떤 것들이 있는지 알려준다.
- NESTED : 충첩 클래스 혹은 인터페이스 여부
1은 클래스의 선언부
- final 혹은 abstract 키워드가 있는지 확인
- extends 뒤에 언급된 부모 클래스 확인
- implements 키워드 뒤의 인터페이스 확인
3. Object 클래스
- 모든 클래스는 Object 클래스의 자식이거나 자손 클래스
- Object 클래스는 JAVA의 모든 클래스의 최상위 부모
객체 비교(equals())
- equals() 메소드의 매개 타입은 Object로 모든 객체가 매개값으로 대입될 수 있다.
- Object 클래스의 equals()메소드는 비교 연산자인 ==와 동일한 결과를 리턴
== 와 equals()는 같은 결과값을 도출하는데 왜 Object클래스는 equals()를 가지고 있을까? -> 재정의를 위해
equals() 메소드를 재정의 하는 경우
- 두 객체가 서로 다르더라도 필드값이 같은 동등 객체인지 비교하기 위해서
- 두 객체의 필드가 모두 같으면 true, 아니며 false 리턴
- equals()메소드는 매개값이 기준 객체와 동일 타입 객체인지 먼저 확인 필요, 즉, 서로 다른 객체더라도 같은 종류의 클래스로 만들어져야 한다.
Member 클래스
package sec02.exam01;
public class Member {
public String id;
public Member(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Member) {
Member member = (Member) obj;
if(id.equals(member.id)) // String이 가지고 있는 equals ->문자열이 같으면 true
return true;
}
return false;
}
}
메인 클래스
package sec02.exam01;
public class MemberExam {
public static void main(String[] args) {
Member obj1 = new Member("blue");
Member obj2 = new Member("blue");
if(obj1.equals(obj2)) { // 원래는 서로 다른 객체를 의미해서 false지만 재정의를 통해 true
System.out.println("동등하다");
} else {
System.out.println("동등하지 않다.");
}
}
}
객체 해시코드(hashCode())
- 객체를 식별하는 하나의 정수값
- Object 클래스의 객체 해시코드 메소드는 객체 메모리 번지를 이용하여 만듦 -> 객체마다 다른 값을 가진다.
- hashCode를 재정의하는 경우 : 두 객체가 동등한지 비교할 때
일반적으로 두 객체가 다를 경우에는 논리적으로 동등하게 만들기 위해서는 equals()와 hashCode도 재정의를 하여 똑같이 만들어주는 작업을 하게 된다.
동등인가 아닌가를 비교할 때 제일 먼저 두 객체의 hashCode를 이용해서 같은지 아닌지를 판단하고 만약 같다면 그 안에 있는 데이터를 비교하기 위해 equals를 호출해서 비교하게 된다.
실제로 이런 원리를 이용해서 동등객체인지 아닌지를 판단하는 자바 API가 있다. HashSet, Hashtable, HashMap같은 경우가 이러하다.
HashMap은 위와 같이 딕셔너리 구조처럼 생겼다. <> 안에는 키와 값의 타입이 작성된다.
package sec02.exam02;
import java.util.HashMap;
public class KeyExam {
public static void main(String[] args) {
// 작성하고 ctrl + shift + o 하면 자동으로 import
HashMap<String,String> hashMap = new HashMap<String,String>();
hashMap.put("key1", "value1");
hashMap.put("key2", "value2");
hashMap.put("key1", "value3"); // 키가 같으면 기존의 키를 제거하고 새것을 저장
System.out.println(hashMap.size()); // size는 키와 값의 쌍이 몇개인지
// 2가 출력
}
}
타입을 String이 아니라 내가 만든 class로 넣는 경우
key 클래스
package sec02.exam02;
public class Key {
public int number;
public Key(int number) {
this.number = number;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key comparKey = (Key) obj;
if(this.number == comparKey.number)
return true;
}
return false;
}
}
메인 클래스
package sec02.exam02;
import java.util.HashMap;
public class KeyExam {
public static void main(String[] args) {
// 작성하고 ctrl + shift + o 하면 자동으로 import
HashMap<Key,String> hashMap = new HashMap<Key,String>();
hashMap.put(new Key(1), "value1");
hashMap.put(new Key(2), "value2");
hashMap.put(new Key(1), "value2");
System.out.println(hashMap.size()); // size는 키와 값의 쌍이 몇개인지
// 3이 출력
}
}
동등객체로 인식되지 않고 3이 출력된다. 이유는 hashMap은 hashCode와 equals를 이용해서 동등비교를 하는데 equals만 재정의가 되었기 때문이다. 따라서 Key 클래스에서 hashCode를 재정의해줘야 한다.
// number가 같은 모든 객체의 hashCode는 같도록 설정
@Override
public int hashCode() {
return number;
}
// 예시2
// Member 클래스
package sec02.exam02;
public class Member {
public String id;
public Member(String id) {
this.id = id;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Member) {
Member member = (Member) obj;
if(id.equals(member.id)) // String이 가지고 있는 equals ->문자열이 같으면 true
return true;
}
return false;
}
@Override
// 해시코드는 기본적으로 객체마다 다 다름
public int hashCode() {
return id.hashCode(); // String타입의 경우 문자열이 같으면 같은 해쉬코드를 가진다.
}
}
// 메인 클래스
package sec02.exam02;
import java.util.HashMap;
public class KeyExam {
public static void main(String[] args) {
HashMap<Member,String> hashMap2 = new HashMap<Member,String>();
hashMap2.put(new Member("fall"), "value2");
hashMap2.put(new Member("winter"), "value2");
hashMap2.put(new Member("fall"), "value2");
System.out.println(hashMap2.size()); // size는 키와 값의 쌍이 몇개인지
}
}
객체 문자 정보(toString())
- Object 클래스의 toString() 메소드는 객체의 문자 정보 리턴
- 기본적으로 ‘클래스이름@16진수해시코드’로 구성된 문자 정보
- toString()메소드를 재정의하는 경우
- 유익한 정보를 리턴하기 위해서
package sec02.exam04;
import java.util.Date;
public class ToStringExam {
public static void main(String[] args) {
Object obj1 = new Object();
Date obj2 = new Date();
System.out.println(obj1.toString()); // java.lang.Object@39ba5a14
System.out.println(obj2.toString()); // Sun Dec 20 17:43:20 KST 2020
}
}
위와 같이 원래는 클래스이름@16진수해시코드로 나오지만 Date 클래스는 toString을 재정의하여 의미있는 값을 리턴한다.
// 스마트폰 클래스
package sec02.exam05;
public class SmartPhone {
private String company;
private String os;
public SmartPhone(String company, String os) {
this.company = company;
this.os = os;
}
@Override
// 의미있는 값으로 재정의
public String toString() {
return company +", " + os;
}
}
// 메인 클래스
package sec02.exam05;
public class SmartPhoneExam {
public static void main(String[] args) {
SmartPhone myPhone = new SmartPhone("구글","안드로이드");
String strObj = myPhone.toString();
System.out.println(strObj);
// 위와 같이 일부러 결과값을 받아서 할 필요가 없다.
// println이 자동적으로 toString을 호출해서 결과를 출력해준다.
System.out.println(myPhone);
}
}