Java 파트11-1. java.lang 패키지

1. 시작하기 전에


  • java.lang 패키지는 자바 프로그램의 기본적인 클래스를 담은 패키지이다.
  • java.lang 패키지의 클래스와 인터페이스는 import 없이 사용할 수 있다.

그림1


2. 자바 API


  • 프로그램 개발에 자주 사용되는 자바에서 제공하는 클래스 및 인터페이스 모음
  • 자바 라이브러리라고도 함
  • API 도큐먼트를 통해 사용방법을 확인할 수 있다.
  • 이클립스에서 클래스 드래그 후 F1키 클릭 - HELP 뷰로 이동 - java.lang.클래스 링크 클릭하면 바로 API 도큐먼트 확인 가능

자바 API 도큐먼트 링크

API 도큐먼트에서 클래스 페이지 읽는 방법

최상단 SUMMARY:NESTED | FIELD | CONSTR | METHOD
클릭했을 때 바로가기가 이동하지 않는다면 없는 것이다.

  • SUMMARY : 클래스 내 선언된 멤버가 어떤 것들이 있는지 알려준다.
  • NESTED : 충첩 클래스 혹은 인터페이스 여부

그림2

1은 클래스의 선언부

  • final 혹은 abstract 키워드가 있는지 확인
  • extends 뒤에 언급된 부모 클래스 확인
  • implements 키워드 뒤의 인터페이스 확인


3. Object 클래스


  • 모든 클래스는 Object 클래스의 자식이거나 자손 클래스
  • Object 클래스는 JAVA의 모든 클래스의 최상위 부모

객체 비교(equals())

  • equals() 메소드의 매개 타입은 Object로 모든 객체가 매개값으로 대입될 수 있다.
  • Object 클래스의 equals()메소드는 비교 연산자인 ==와 동일한 결과를 리턴

그림3

== 와 equals()는 같은 결과값을 도출하는데 왜 Object클래스는 equals()를 가지고 있을까? -> 재정의를 위해

equals() 메소드를 재정의 하는 경우

  • 두 객체가 서로 다르더라도 필드값이 같은 동등 객체인지 비교하기 위해서
  • 두 객체의 필드가 모두 같으면 true, 아니며 false 리턴
  • equals()메소드는 매개값이 기준 객체와 동일 타입 객체인지 먼저 확인 필요, 즉, 서로 다른 객체더라도 같은 종류의 클래스로 만들어져야 한다.

그림4

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도 재정의를 하여 똑같이 만들어주는 작업을 하게 된다.

그림5

동등인가 아닌가를 비교할 때 제일 먼저 두 객체의 hashCode를 이용해서 같은지 아닌지를 판단하고 만약 같다면 그 안에 있는 데이터를 비교하기 위해 equals를 호출해서 비교하게 된다.
실제로 이런 원리를 이용해서 동등객체인지 아닌지를 판단하는 자바 API가 있다. HashSet, Hashtable, HashMap같은 경우가 이러하다.

그림6

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);
		

	}

}



본 포스팅은 ‘혼자 공부하는 자바’를 읽고 공부한 내용을 바탕으로 작성하였습니다.


© 2021. By Backtony