수업 시작에 앞서...
초창기 자바는 그 규모가 크지 않았다. 지금이 빌딩이라고 하면 초기에는 초가집?
지금은 규모가 너무 커져서 세세한 내용까지 모두 공부할 수가 없다. 자주 이용하고, 필요하고, 숙지해야할 내용만 배우고 나중에 필요할 때 작은 부분까지 알아가면 된다.
오늘부터 배울 주요(중요) 클래스 파트는 자바가 제공하는 클래스로 무엇이 있는지, 어떤 것이 유용할지, 주의해야하는 것은 어떤 것인지 관찰하는 파트이다. (개발하는 파트 Ⅹ)
교재를 쓱- 살펴보면서 어떤 클래스들이 제공되는지 타이틀을 확인해보자.
Object, String, StringBuffer, Math, Wrapper, Number, 오토박싱 언박싱, Random, 정규식, Scanner, StringTokenizer, BigInteger, BigDecimal...
클래스에 포함된 메소드에 대한 설명이 나오면 반환형과 메소드이름을 관찰해보자.
자바에서 제공하는 클래스들을 공부하려면 java.sun.com 에서 제공하는 api documentation를 자주 참조하면서 봐야한다. 수업 중에 예제로 배우는 메소드, 클래스에 대해서 api 문서를 찾아가 굵은 글씨 위주로 훑어만 보자. (링크는 JDK8 기준!)
※ api 문서로 클래스 보는 방법
package
일반적으로 클래스는 하나만 존재하는 것이 아니라 같은 종류의 클래스를 여러 개 묶어서 사용하게 되는데 이러한 클래스나 인터페이스의 묶음을 패키지(package)라고 한다.
Sun(Oracle)사에서는 자바 프로그램을 효율적으로 작성할 수 있도록 자바 표준 패키지를 제공하며, 자바 표준 패키지에는 그래픽, 네트워크, 데이터베이스 등의 다양하고 유용한 클래스들이 포함되어 있다.
패키지는 필요에 따라 사용자에 의해 만들 수도 있다. 소스코드의 첫번째 줄에 package 를 선언한다.
import 구문
자바 표준 패키지나 사용자에 의해 외부에서 만들어진 패키지를 사용하기 위해서는 컴파일을 수행하기에 앞서 프로그램에 포함시키는 과정이 필요한데, 이 때, 『import』 문을 이용하여 패키지 또는 클래스를 프로그램에 포함시키게 된다.
하지만, 『java.lang.*』 패키지는 자바 프로그램에 기본적으로 import 되어 있기 때문에 이 패키지의 클래스들은 import 하지 않고 바로 사용하는 것이 가능하다.
import 문은 반드시 클래스 설계 구문 전에 선언되어 있어야하며(class 설계부 보다 위에) 형식은 다음과 같은 두 가지가 있다.
import [static] 패키지.클래스; // 클래스 하나만 프로그램에 포함
import [static] 패키지.*; // 패키지에 속한 모든 클래스를 프로그램에 포함
※ JDK 1.5 부터는 import 다음에 『static』 키워드를 붙임으로써 정적으로 패키지를 import 할 수 있는 기능을 제공하게 되었다. 만약 패키지를 정적(static)으로 import 한 경우라면 모든 접근 가능한 메소드와 멤버 변수들은 접두사(ob, br, sc 처럼...)를 붙이지 않고 사용하는 것이 가능하다.
Object 클래스
『java.lang.Object』 클래스는 자바 클래스의 최상위 클래스로 자바 표준 패키지의 클래스나 사용자에 의해 작성된 모~~~~~~든 클래스는 기본적으로 이 클래스로부터 상속받는다. 따라서 자바의 모든 클래스는 『java.lang.Object』 클래스의 메소드를 가지고 있으며, Object의 메소드를 바로 사용하는 것이 가능하다.
Object 예제 코드 1 - 예제에 앞서 정의하지 않은 메소드의 호출에 대한 고찰
생성된 인스턴스의 메소드에 접근할 때, 클래스에 정의하지 않는 메소드를 호출하면 당연히 에러가 발생한다.
아래 예제코드에서는 임의로 설계한 Test131클래스로 인스턴스를 생성하고 정의하지도 않은 toString() 메소드를 호출해 볼 것이다. (사실 지난 포스팅에서 언급한 것처럼 toString() 메소드는 Object 클래스에 포함된 메소드이다.)
Test131 클래스는 아무것도 상속(extends)받지 않았지만 우리도 모르게 Object 클래스를 상속받았음을 알 수 있다.
toString() 메소드를 호출하여 반환된 결과값을 println()으로 출력하면 다음과 같이 출력된다.
『클래스명@16진수해시코드』
@ 뒤에 따라오는 16진수 해시코드는 자바가 내부적으로 객체를 구분하기 위해 임의로 부여하는 식별번호이다. 메모리의 주소값이 아니다.
/*=================================
■■■ 자바의 주요(중요)클래스 ■■■
=================================*/
// Test132.java 와 비교~!!!
//import java.lang.*;
// → import java.lang.Object;
public class Test131 // extends Object
{
/* Object 클래스로부터 상속받은 멤버들
...
...
String toString() { ... }
...
*/
// 논외 : default 생성자의 접근제어지시자는 그 클래스의 접근제어지시자를 그대로 따른다.
/* 생략되어있는 Test131 의 default 생성자
public Test131() { } // public class 이므로 생성자도 public
*/
public static void main(String[] agrs)
{
Test131 ob = new Test131();
// 객체.xxx();
//-- 해당 객체를 생성시키는 대상 클래스에 xxx() 메소드가 존재하지 않을 경우 → 에러 발생
//ob.test(); // 에러 발생. test() 메소드는 Test131 클래스에 존재하지 않는 메소드.
//System.out.println(ob.test()); // 당연히 에러발생
System.out.println(ob.toString());
//--==>> Test131@15db9742
//-- 에러가 발생하지 않음 → toString() 메소드가 Test131 클래스에 존재
// → Object 클래스로부터 상속받은 메소드
System.out.println(ob);
//--==>> Test131@15db9742
// 객체 ob를 출력한 것과 toString() 의 결과값(반환값)을 출력한 것과 같은 문자열이 출력된다.
}
}
Object 예제 코드 2 - toString() 메소드의 오버라이딩(재정의)
예제 코드 1과 출력 결과를 비교해보자.
여기서도 객체와 toString() 메소드의 결과값을 println()로 출력해보고 있다.
결과가 같은 것을 보았을 때 toString() 메소드가 반환하는 결과값은 그 객체(클래스)의 정보나 값을 대표한다고 볼 수 있다. 따라서 클래스를 설계할 때 toString() 메소드를 재정의하여 의미있는 값을 반환할 수 있다.
/*=================================
■■■ 자바의 주요(중요)클래스 ■■■
=================================*/
// Test131.java 와 비교~!!!
//import java.lang.*;
// → import java.lang.Object;
public class Test132 // extends Object
{
/*
Object 클래스로부터 상속받은 멤버들
...
public String toString()
{
}
*/
@Override
public String toString()
{
return "재정의한 toString()...";
}
public static void main(String[] agrs)
{
Test132 ob = new Test132();
System.out.println(ob.toString());
//--==>> 재정의한 toString()...
System.out.println(ob);
//--==>> 재정의한 toString()...
// 객체 ob를 출력한 것과 toString() 의 결과값(반환값)을 출력한 것과
// 같은 문자열이 출력되는 것을 다시 한번 확인할 수 있다.
// 객체 자체 출력 == toString() 메소드의 결과값 출력
}
}
Object 예제 코드 3 - Object(객체)의 비교(==연산자, equals() 메소드)
두 객체의 ==연산자를 통한 비교연산 : 주소값 비교
Object의 equals() 메소드를 통한 비교 : 주소값 비교
★ 객체가 같으면 hashcode(해시코드)가 같지만 hashcode(해시코드)가 같다고 해서 같은 객체는 아니다. ★
/*=====================================
■■■ 자바의 주요(중요)클래스 ■■■
- Object 클래스
=====================================*/
//import java.lang.*;
class Test // extends Object
{
/* Object 로부터 상속받은 equals() 메소드
public boolean equals(Object obj) { }
*/
private int a = 10;
public void write()
{
System.out.println("a : " + a);
}
}
// main()을 포함하고 있는 클래스
public class Test133
{
public static void main(String[] agrs)
{
Test ob1 = new Test();
Test ob2 = new Test();
System.out.println("10 == 9 : " + (10 == 9)); // 상수의 비교연산(==)
//--==>> 10 == 9 : false
int a = 10;
int b = 10;
System.out.println("a == b : " + (a == b)); // 변수의 비교연산(==)
//--==>> a == b : true
System.out.println("ob1 == ob2 : " + (ob1 == ob2)); // 인스턴스의 비교연산(==)
//--==>> ob1 == ob2 : false
//-- 객체(Object)들을 비교하는 과정에서의 『==』 연산자는
// 객체의 크기를 비교하는 것이 아니라 객체의 주소값을 비교.
// Object - 『equals()』 메소드
System.out.println("ob1.equals(ob2) : " + (ob1.equals(ob2)));
//--==>> ob1.equals(ob2) : false
//-- 『==』 연산자와 Object 클래스의 『equals()』 메소드는 동일한 개념으로
// 객체의 주소값을 비교.
System.out.println();
System.out.println("-----------------------------------");
System.out.println();
System.out.println("ob1 : " + ob1);
System.out.println("ob1.toString() : " + ob1.toString());
//--==>> ob1 : Test@15db9742
// ob1.toString() : Test@15db9742
// ※ 해시코드(hashcode)
// : 자바 내부적으로 객체를 구분하기 위해 사용하는 것으로,
// 메모리의 주소값으로 생각하면 절대로 안된다.
// check~!!! (★ 중요)
// ※ 객체가 같으면 hashcode(해시코드)가 같지만
// hashcode(해시코드)가 같다고 해서 같은 객체는 아니다.
}
}
Object 예제 코드 4 - 여러가지 Object 클래스의 메소드
반환형 | 메소드이름(매개변수) | 설명 |
boolean | equals(Object obj) | 주소값 비교 |
String | toString() | 객체의 정보를 문자열로 반환 |
int | hashcode() | 객체의 hashcode 값 반환. 16진수로 변환하면 toString() 반환값의 @ 뒤의 hashcode 값과 같다. |
Class<?> | getClass() | getClass() 메소드를 호출하는 인스턴스가 어떤 클래스를 기반으로 생성된 것인지 확인할 수 있다. 이 메소드의 반환값에 대해서는 나중에 배우니 일단 넘어가자. |
protected Object | clone() | 객체의 깊은 복사. 깊은 복사가 이루어지면 복제된 객체를 변경해도 원본 데이터의 변경이 없다. 복제객체와 원본객체가 별개이다. (얕은 복사는 주소값의 복사이므로 복사된 객체를 수정하면 원본 객체의 내용도 같이 변한다.) |
/*=====================================
■■■ 자바의 주요(중요)클래스 ■■■
- Object 클래스
=====================================*/
class NewCar
{
private int velocity; //-- 자동차의 속도
private int wheelNum; //-- 자동차의 바퀴 갯수
private String carName; //-- 자동차의 이름
NewCar(int speed, String name, int wheel)
{
velocity = speed;
carName = name;
wheelNum = wheel;
}
}
public class Test134
{
public static void main(String[] args)
{
NewCar nCar1 = new NewCar(100, "볼보", 4);
NewCar nCar2 = new NewCar(150, "BMW", 4);
// 1. Object - equals() 메소드
System.out.println("1-1 : " + nCar1.equals(nCar2)); //equals : 주소값 비교
System.out.println("1-2 : " + (nCar1 == nCar2)); // == : 주소값 비교
//--==>> 1-1 : false
// 1-2 : false
NewCar nCar3 = nCar1; //-- 객체 복사 → 얕은 의미 복사(참조형) → 주소값 복사★
System.out.println("2-1 : " + nCar1.equals(nCar3));
System.out.println("2-2 : " + (nCar1 == nCar3));
//--==>> 2-1 : true
// 2-2 : true
// 3. Object - toString() 메소드
System.out.println("3-1 : " + nCar1.toString());
System.out.println("3-2 : " + nCar2.toString());
System.out.println("3-3 : " + nCar3.toString());
//--==>> 3-1 : NewCar@15db9742
// 3-2 : NewCar@6d06d69c
// 3-3 : NewCar@15db9742
// 4. Object - hashCode() 메소드
System.out.println("4-1 : " + nCar1.hashCode());
System.out.println("4-2 : " + nCar2.hashCode());
System.out.println("4-3 : " + nCar3.hashCode());
//--==>> 4-1 : 366712642
// 4-2 : 1829164700
// 4-3 : 366712642
//-- 결과값을 16진수 형태로 바꾸게 되면 『toString()』메소드가 반환한 결과값 확인 가능.
// 5. Object - getCalss() 메소드
System.out.println("5-1 : " + nCar1.getClass());
System.out.println("5-2 : " + nCar2.getClass());
System.out.println("5-3 : " + nCar3.getClass());
//--==>> 5-1 : class NewCar
// 5-2 : class NewCar
// 5-3 : class NewCar
//-- 생성된 객체가 어떤 클래스를 기반으로하는지 확인할 수 있는 기능의 메소드
// Object - clone() //-- 객체 복사(깊은 복사)
// 데이터를 수정해도 원본 객체에 영향을 끼치지 않음
// Object - finalize()
// 기타 나머지 메소드는 스레드 처리와 관련이 있다. (지금 당장 안봐도 된다)
}
}
'자바 풀스택 과정 수업 정리 > 자바' 카테고리의 다른 글
자바 17-3 (2020.08.26) : 자바의 주요(중요) 클래스 - String (0) | 2020.09.11 |
---|---|
자바 17-2 (2020.08.26) : 자바의 주요(중요) 클래스 - Wrapper (0) | 2020.09.07 |
자바 16-3 (2020.08.25) : 중첩클래스(중첩 내부클래스, 내부클래스, 로컬클래스, 익명클래스) (0) | 2020.09.06 |
자바 16-2 (2020.08.25) : 인터페이스 (0) | 2020.09.05 |
자바 16-1 (2020.08.25) : 상속 관계의 형변환, 업캐스팅, 다운캐스팅, 인터페이스, 중첩클래스(중첩 내부클래스, 내부클래스, 로컬클래스, 익명클래스) (0) | 2020.09.04 |
최근댓글