프로그래밍/Java 공부

모듈과 패키지 개념, 자바 기본 패키지

개발계발게발 2020. 12. 13. 23:30
반응형

패키지

패키지 : 서로 관련 있는 클래스나 인터페이스의 컴파일된 클래스(.class) 파일들을 서로 관련 있는 것들끼리 한곳에 묶어 놓은 것

- 하나의 패키지 = 하나의 디렉터리에 저장된 클래스 파일들을 지칭

- 클래스를 지칭할 때는 패키지명을 포함하는 경로명을 사용

ex) java.awt.Color : 클래스의 이름 (경로명) / java.awt : 패키지명

1. 패키지 계층 구조

2. 패키지별 접근 제한 - 패키지 간 무단 접근 방지 가능

3. 동일한 이름의 클래스를 다른 패키지에 작성 가능

ex) 파일 시스템이 같은 이름을 가진 파일이 다른 디렉터리에 있으면 서로 다른 파일로 인지하는 것과 같음

4. 소프트웨어의 높은 재사용성

∵ 불필요한 코딩 작업을 줄여주기 때문

cf) 자바 개발 도구인 JDK(Java Development Kit)에서는 패키지 이름은 소문자로 시작하고 클래스 이름은 대문자로 시작한다.

package 선언문을 사용하지 않으면 자바 컴파일러는 클래스나 인터페이스를 디폴트 패키지(default package)에 소속시킨다.

디폴트 패키지 = 기본 패키지 = 현재 디렉터리

+

java.lang : System을 비롯하여 문자열, 수학 함수, 입출력 등과 같이 자바 프로그래밍에 필요한 기본적인 클래스와 인터페이스를 제공한다. 이 패키지의 클래스들은 특별히 import 문을 사용하지 않아도 자동으로 임포트된다.

import문

 

: 다른 패키지의 클래스를 사용할 때, 컴파일러에게 그 클래스의 경로명을 알려주는 문

 

1. import 패키지.클래스; //클래스의 경로명을 컴파일러에게 알려주는 문

 

2. import 패키지.*; //한 캐피지에 있는 여러 클래스의 경로명을 한 번에 지정하려면, *로 하면 된다.

 

- import 문은 반드시 클래스(class) 소스 코드 전 에 작성되어야 한다.

패키지선언

: 클래스가 소속될 패키지 명을 package 키워드를 이용하여 소스 파일의 첫 줄에 선언한다. (import가 먼저 오면

 

package Graphic; //Line 클래스를 Graphic 패키지에 저장

import UI.Tools; //사용할 Tools 클래스의 경로명 알림

public class Line {
  public void draw() {
    Tools t = new Tools();
  }
}

 

모듈 개념

 

모듈 JAVA 9에서 처음 도입된 개념

패키지는 서로 관련 있는 클래스나 인터페이스의 컴파일된 클래스(.class) 파일들을 한 곳에 담는 컨테이너

모듈은 패키지들을 담는 컨테이너로 모듈 파일(.jmod)로 저장됨​

 

자바 모듈화의 목적

 

자바 컴포넌트들을 필요에 따라 조립하여 사용하기 위함(필요없는 모듈이 로드되지 않게 하여 시스템 부담 감소)

ex) 하드웨어가 열악한 소형 IoT 장치에서 사용

 

자바 JDK 패키지 

 

java.lang

 - System을 비롯하여 문자열, 수학 함수, 입출력 등과 같이 자바프로그래밍에 필요한 기본 클래스와 인터페이스를 제공

   import 문을 사용하지 않아도 자동으로 임포트된다.

 

java.util

 - 날짜, 시간, 벡터, 해시맵 등 다양한 유틸리티 클래스와 인터페이스를 제공

 

java.io

 - 키보드, 모니터, 프린터, 파일 등에 입출력 하는 클래스와 인터페이스를 제공

 

java.awt와 javax.swing

 - 자바 AWT(Abstract Windowing Toolkit)와 swing 패키지로서 GUI 프로그래밍에 필요한 클래스와 인터페이스를 제공

 

* 개발자는 JDK의 클래스가 가진 메소드를 전부 기억하거나 이해할 수 없기 때문에

   항상 자바 API문서를 열어놓고 작업하는게 좋다.

 

: java.lang 패키지에 속한 클래스로 모든 클래스는 묵시적으로 Object를 상속받는.

Object 만이 아무 클래스도 상속받지 않는 유일한 클래스로 계층 구조 상 최상위 클래스이다.

Object 클래스에는 모든 클래스에서 사용할 공통 기능이 구현되어 있다.

 

Object의 주요 메소드

메소드 설명
boolean equals(Object obj)  obj가 가리키는 객체와 현재 객체를 비교하여 같으면 true 리턴
Class getClass() 현 객체의 런타임 클래스를 리턴
int hashCode() 현 객체에 대한 해시 코드 값 리턴
String toString() 현 객체에 대한 문자열 표현을 리턴
void notify() 현 객체에 대해 대기하고 있는 하나의 스레드를 깨운다
void notifyAll() 현 객체에 대해 대기하고 있는 모든 스레드를 깨운다
void wait() 다른 스레드가 깨울 때까지 현재 스레드를 대기하게 한다.

 

class Point{
	int x, y;
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
}

public class ObjectPropertyEx {
	public static void print(Object obj) {
		System.out.println(obj.getClass().getName()); // 클래스 이름
		System.out.println(obj.hashCode()); // 해시 코드 값
		System.out.println(obj.toString()); // 객체를 문자열로 만들어 출력
		System.out.println(obj); // 객체 출력
	}

	public static void main(String[] args) {
		Point p = new Point(2,3);
		print(p);

	}

}

getName() 메소드를 이용하면 obj 레퍼런스가 가리키는 객체의 클래스 타입을 알아낼 수 있다.

 

객체는 생성될 때 객체를 유일하게 구분할 수 잇 는 정수 id값 할당(해시코드)

 

 

ex) toString( ) : 객체를 문자열로 리턴하는 메소드 ∴ '객체 + 문자열' 연산 / 객체 출력시 자동 호출

public String toString() { 
return getClass.getName() + "@" + Integer.toHexString(hashCode());
}
//객체의 클래스의 이름 @ 객체의 해시코드 값을 16진수로 변환하여 연결한 문자열 리턴

System.out.println(p); // System.out.println(p.toString()); 으로 자동으로 변환
String s = p + "점"; //String s = p.toString() + "점";으로 자동 변환
System.out.println(s);
class Point{
	int x, y;
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	public String toString() {
		return "Point(" + x + "," + y + ")";
	}
}
public class ToStringEx {
	public static void main(String[] args) {
		Point p = new Point(2,3);
		System.out.println(p.toString());
		System.out.println(p); //p는 p.toString()으로 자동 변환
		System.out.println(p + "입니다."); // p.toString() + "입니다"로 자동 변환
	}
}

 

객체 비교와 equals() 메소드

기본타입의 값을 비교하기 위해서 == 연산자

객체 비교를 위해서는 반드시 equal() 메소드를 사용​

 

Point a = new Point(2,3);
Point a = new Point(2,3);
Point c = a;
if(a == b) //false
	System.out.println("a==b");
if(a == c) //true
	System.out.println("a==c");

실행 결과    -    a==c

 

String a = new String("Hello");
String b = new String("Hello");
if(a == b) //false
System.out.println("a==b");
if(a.equals(b))//true
System.out.println("a와 b는 둘 다 Hello입니다.");

실행 결과   -   a와 b는 둘 다 Hello입니다.

 

이유) a와 b의 레퍼런스 값다르기 때문에 a == b 의 결과가 false + 둘 다 ""로 선언된 것이 아니라 new String으로 선언되어서

== 는 두 객체의 내용물이 같은지 비교하는 것이 x, 두 레퍼런스가 같은지 비교

두 레퍼런스가 동일한 객체를 가리키는지 비교

equals(Object obj)는 인자로 건네진 객체 obj와 자기 자신을 비교하여 두 객체의 내용이 같은지를 비교하는 메소드

- 사실, 내용의 동일성은 전적으로 클래스 작성자가 정의할 문제이기 때문에

  클래스 작성자가 클래스에 equals( ) 메소드를 오버라이딩 하는 것이 원칙

class Point{
	int x, y;
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}
	public boolean equals(Object obj) {//equals() 오버라이딩
		Point p = (Point)obj;	// 객체 obj를 Point 타입으로 다운 캐스팅
		if(x == p.x && y == p.y)
			return true;
		else
			return false;		
	}
}
public class EqualEx {
	public static void main(String[] args) {
		Point a = new Point(2,3);
		Point b = new Point(2,3);
		Point c = new Point(3,4);
		if(a == b)  // false
			System.out.println("a==b");
		if(a.equals(b)) // true
			System.out.println("a is equal to b");
		if(a.equals(c)) // false
			System.out.println("a is equal to c");
	}
}

 

class Rect{
	int width;
	int height;
	public Rect(int width, int height) {
		this.width = width;
		this.height = height;
	}
	public boolean equals(Object obj) {//equals() 오버라이딩 사각형 면적 비교
		Rect p = (Rect)obj;	// obj를 Rect로 다운 캐스팅
		if(width*height == p.width*p.height)
			return true;
		else
			return false;		
	}
}
public class RectEqualsEx {
	public static void main(String[] args) {
		Rect a = new Rect(2,3);
		Rect b = new Rect(3,2);
		Rect c = new Rect(3,4);
		if(a.equals(b))  // true  a와 b는 면적 이 같으므로 equlas()는 true 리턴
			System.out.println("a is equal to b");
		if(a.equals(c)) // false
			System.out.println("a is equal to c");
		if(b.equals(c)) // false
			System.out.println("b is equal to c");
	}
}

 

​Wrapper 클래스 개념

int, char, double 등 8개의 기본 타입을 객체로 다루기 위해 JDK에 만들어진 8개의 클래스를 Wrapper 클래스라 한다.

 

: Byte, Short, Integer, Long, Character, Double, Float, Boolean 클래스가 기본 타입에 해당되는 값(ex. 3, 'a')을 객체로 다룰 수 있게 하는 클래스

기본 타입 byte short int long char float double boolean
Wrapper 클래스 Byte Short Integer Long Character Float Double Boolean

Wrapper 클래스의 객체 생성

Integer i = Integer.calueOf(10);		// 정수 10의 객체화
Character c = Character.valueOf('c');	// 문자 'c'의 객체화
Double d = Double.valueOf(3.14);		// 실수 3.14의 객체화
Boolean b = Boolean.valueOf(true);		// 불린 값 true의 객체화

Character를 제외한 나머지 Wrapper 클래스의 경우 문장려로 WRapper 객체를 생성할 수도 있다.

 

Integer i = Integer.valueOf("10");
Double d = Double.valueOf("3.14");

 

- 많은 메소드가 static 타입

 

Wrapper 객체에 들어 있는 기본 타입 값 알아내기

Integer i = Integer.valueOF(10);
int ii = i.intValue();	// ii = 10

Double d = Double.valueOf(3.14);
double dd = d.doubleValue();	// dd = 3.14

Boolean b = Boolean.valueOf(true);
boolean bb = b.booleanValue();	// bb = true

 

문자열을 기본 타입으로 변환

Wrapper 클래스는 다음과 같이 문자열을 기본 타입의 값으로 변환하는 메소드를 제공

int i = Integer.parseInt("123");			// i = 123
boolean b = Boolean.parseBoolean("true");	// b = true
double d = Double.parseDouble("3.14");		// d = 3.14

- parseInt( ), parseBoolean( ), parseDouble( ) 메소드는 모두 static 타입이므로 Wrapper 클래스의 이름으로 바로 메소드를 호출한다.

 

기본 타입 값을 문자열로 변환

String s1 = Integer.toString(123);		// 정수 123을 문자열 "123"으로 변환
String s2 =	Integer.toHexString(123);	// 정수 123을 16진수의 문자열 "7b"로 변환
String s3 = Double.toString(3.14);		// 실수 3.14를 문자열 "3.14"로 변환
String s4 = Character.toString('a');	// 문자 'a'를 문자열 "a"로 변환
String s5 = Boolean.toString(true);		// 불린 값 true를 문자열 "true"로 변환
public class WrapperEx {
	public static void main(String[] args) {
		System.out.println(Character.toLowerCase('A'));	// 'A'를 소문자로 변환
		
		char c1='4', c2='F';
		if(Character.isDigit(c1))		// 문자 c1이 숫자이면 true
			System.out.println(c1 + "는 숫자");
		if(Character.isAlphabetic(c2))	// 문자 c2가 영문자이면 true
			System.out.println(c2 + "는 영문자");
		
		System.out.println(Integer.parseInt("-123"));	// "-123"을 10진수로 변환
		System.out.println(Integer.toHexString(28));	// 정수 28을 2진수 문자열로 변환
		System.out.println(Integer.toBinaryString(28)); // 28을 16진수 문자열로 변환
		System.out.println(Integer.bitCount(28));		// 28에 대한 2진수의 1의 개수
		
		Double d = Double.valueOf(3.14);
		System.out.println(d.toString());				// Double을 문자열 "3.14"로 변환
		System.out.println(Double.parseDouble("3.14"));	// 문자열을 실수 3.14로 변환
		
		Boolean b = (4>3); //b는 true
		System.out.println(Boolean.toString(b));			// true를 문자열 "true"로 변환
		System.out.println(Boolean.parseBoolean("false"));	// 문자열을 false로 변환
	}
}

실행 결과

기본 타입의 값 → Wrapper 객체로 변환 : 박싱(boxing)

(오른쪽의 기본 타입의 값을 / 왼쪽 Wrapper 객체에 삽입하는 것이 박싱)

반대 : 언박싱(unboxing)

- 둘 다 자동으로 이루어지며, 이를 자동 박싱(auto boxing), 자동 언박싱(auto unboxing) 이라고 부른다.

Integer ten = 10; //자동 박싱. Integer ten = new Integer(10);로 자동 처리됨

int n = ten; //자동 언박싱. int n = ten.intValue();로 자동 처리됨

String 클래스

//스트링 리터럴로 String 객체 생성
String str1 = "abcd";

//String 클래스의 생성자를 이용하여 String 객체 생성
char data[] = {'a', 'b', 'c', 'd'};
String str2 = new String(data);
String str3 = new String("abcd");
String str4 = new String(str1); //str2와 str3은 모두 "abcd" 문자열

스트링 리터럴과 new String()으로 생성된 개체는 서로 다르게 관리

스트링 리터럴은 자바 내부에서 리터럴 테이블로 특별 관리하여, 동일한 리터럴을 공유시킨다.

new String( )으로 생성된 스트링은 new를 이용하여 생성되는 다른 객체와 동일하게 힙 메모리독립적으로 생성된다.

+ scanner.nextLine( ) 으로 받은 것도 힙 메모리 독립 생성 !!!

 

public class StringEx {
	public static void main(String[] args) {
		String a = new String(" C#");
		String b = new String(",C++ ");
		
		System.out.println(a + "의 길이는 " + a.length()); //문자열의 길이(문자 개수) 3
		System.out.println(a.contains("#"));	//문자열의 포함 관계  - true
		
		a = a.concat(b); //문자열 연결  - a = " C#,C++ "
		System.out.println(a);
		
		a = a.trim(); 	//문자열 앞 뒤의 공백 제거	- a = "C#,C++"
		System.out.println(a);
		
		a = a.replace("C#","Java");	//문자열 대치  - a = "Java,C++"
		System.out.println(a);
		
		String s[] = a.split(","); 	//문자열 분리  - s[0] = "Java"  ,  s[1] = "C++"
		
		for(int i=0; i<s.length; i++)
			System.out.println("분리된 문자열" + i + ": "+ s[i]);
		
		a = a.substring(5); 		//인덱스 5부터 끝까지 서브 스트링 리턴
		System.out.println(a);
		
		char c = a.charAt(2);	//인덱스 2의 문자 리턴
		System.out.println(c);
		c = a.charAt(0);	//인덱스 0의 문자 리턴
		System.out.println(c);

	}

}

 

StringBuffer 클래스란?

스트링을 다루는 클래스

String 객체의 경우 내부의 문자열을 수정할 수 없다.

StringBuffer 객체는 가변 버퍼를 가지고 있기 때문에 문자의 개수에 따라 버퍼 크기를 자동 조절한다.

스트링의 수정 가능

 

String - 간단한 문자열을 처리할 때 ∵ 문자열 변경/수정이 불가능 하기 때문

StringBuffer - 문자열의 길이가 길거나 문자열이 수시로 변하는 경우

 

	public static void main(String[] args) {
	StringBuffer sb = new StringBuffer("This");
	
	sb.append(" is pencil");	// 문자열 덧붙이기
	System.out.println(sb);
	
	sb.insert(7, " my"); 		// " my" 문자열 삽입
	System.out.println(sb);
	
	sb.replace(8, 10, "your"); 	// "my"를 "your"로 변경
	System.out.println(sb);
	
	sb.delete(8, 13);			// "your" 삭제
	System.out.println(sb);
	
	sb.setLength(4);			// 스트링 버퍼 내 문자열 길이 수정
	System.out.println(sb);		// sb.toString()으로 자동 바뀜	
	}
}

StringTokenizer - 문자열을 분할할 때

package 모듈과패키지;

import java.util.StringTokenizer;

public class StringTokenizerEx {
	public static void main(String[] args) {
		StringTokenizer st = new StringTokenizer("홍길동=김철수&장화=홍련&콩쥐=팥쥐","=&");//구분 문자 =,&
		
		while(st.hasMoreTokens())	//토큰이있는동안
			System.out.println(st.nextToken());
	}

}

+ toString( ) 예시

public String toString() { return "Point(" + x + "," + y + ")"; }

 

Math 클래스

 

Random() 난수 발생 - 0.0<=1.0 임의의 실수 리턴

 

1~100까지(100포함) 난수 발생 코드

for(int x=0; x<10; x++){
	int n = (int)(Math.randon()*100 + 1);	// n은 [1~100] 사이의 랜덤 정수
    System.out.println(n);
}

 

java.util.Random 클래스도 난수 발생 가능

Random r = new Random();
int n = r.nextInt();	// 음수, 양수, 0을 포함하여 자바의 정수 범위(-2^31~2^31-1)의 난수 발생
int m = r.nextInt(100);	// 0~99사이(0과 99 포함)의 정수 난수 발생

 

public class MathEx {
	public static void main(String[] args) {
		System.out.println(Math.PI);	//원주율 상수 출력
		double a = Math.PI;
		System.out.println(Math.ceil(a));		//ceil(올림)
		System.out.println(Math.floor(a));		//floor(내림)
		System.out.println(Math.sqrt(a));		//제곱근
		System.out.println(Math.sqrt(9));		//제곱근
		System.out.println(Math.exp(2));		//e의 2승
		System.out.println(Math.round(3.14));	// 반올림
		
		// [1,45] 사이의 정수형 난수 6개 발생
		System.out.print("이번주 행운의 번호는 ");
		for(int i=0; i<6; i++)
			System.out.print((int)(Math.random()*45+1)+ " ");  	// 난수 발생
	}
}

 

Calendar 클래스

년, 월, 일, 요일, 시간, 분, 초, 밀리초까지 프로그램이 실행되는 동안 개발자가 기억하고자 하는 시관과 날짜정보를 저장

 

package 모듈과패키지;

import java.util.Calendar;

public class CalendarEx {
	public static void printCalendar(String msg, Calendar cal) {
	    int year = cal.get(Calendar.YEAR);
	    int month = cal.get(Calendar.MONTH) + 1; // get()은 0~30까지의 정수 리턴.
	    int day = cal.get(Calendar.DAY_OF_MONTH);
	    int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
	    int hour = cal.get(Calendar.HOUR);
	    int hourOfDay = cal.get(Calendar.HOUR_OF_DAY);
	    int ampm = cal.get(Calendar.AM_PM);
	    int minute = cal.get(Calendar.MINUTE);
	    int second = cal.get(Calendar.SECOND);
	    int millisecond = cal.get(Calendar.MILLISECOND);

	    System.out.print(msg + year + "/" + month + "/" + day + "/");
	    switch(dayOfWeek) {
		    case Calendar.SUNDAY : System.out.print("일요일"); break;
		    case Calendar.MONDAY : System.out.print("월요일"); break; 
		    case Calendar.TUESDAY : System.out.print("화요일"); break;
		    case Calendar.WEDNESDAY : System.out.print("수요일"); break;
		    case Calendar.THURSDAY : System.out.print("목요일"); break;
		    case Calendar.FRIDAY: System.out.print("금요일"); break;
		    case Calendar.SATURDAY : System.out.print("토요일"); break;
	    }
	    System.out.print("("+ hourOfDay + "시)");
	    if(ampm == Calendar.AM) 
	    	System.out.print("오전");
	    else
	    	System.out.print("오후");
	    
	    System.out.println(hour + "시 " + minute + "분 " + second + "초 " +
	    					millisecond + "밀리초");
	}

	public static void main(String[] args) {
	    Calendar now = Calendar.getInstance();
	    printCalendar("현재 ", now);
 
	    Calendar firstDate = Calendar.getInstance();
	    firstDate.clear();
	    firstDate.set(2019, 10, 03); // 2019년 11월 03일. 11월을 표현하기 위해 month에 10로 설정
	    firstDate.set(Calendar.HOUR_OF_DAY, 20); // 저녁 8시
	    firstDate.set(Calendar.MINUTE, 30); // 30분
	    printCalendar("처음 만나기로 한 날은 ", firstDate);
	}
}

 

반응형

'프로그래밍 > Java 공부' 카테고리의 다른 글

연산자, 조건문(if, else if)  (0) 2021.05.20
변수, 데이터 타입, 형변환  (0) 2021.05.19
입출력 스트림과 파일 입출력  (0) 2020.12.29
제네릭과 컬렉션  (0) 2020.12.22
JAVA 상속  (0) 2020.12.12