[자바의 정석] 패키지

YJS·2023년 11월 20일
0

1. package 키워드


패키지란?

클래스의 묶음. 서로 관련된 클래스들끼리 그룹 단위로 묶어 놓음으로써 클래스를 효율적으로 관리.

→ 같은 이름의 클래스 일지라도 서로 다른 패키지에 존재하는 것이 가능. 충돌 예방.

→ String 클래스의 풀네임은 java.lang.String (lang 패키지에 속한 String클래스)

-하나의 소스파일에는 첫번째 문장으로 단 한번의 패키지 선언만을 허용

-모든 클래스는 반드시 하나의 패키지에 속해야함

-패키지는 점을 구분자로 하여 계층구조 구성 가능

-패키지는 물리적으로 클래스파일을 포함하는 하나의 디렉토리

<패키지 선언>

 package 패키지명;

→ 반드시 소스파일에서 주석과 공백을 제외한 첫번째 문장.

→하나의 소스파일에 단 한번만 선언

→해당 소스파일에 포함된 클래스나 인터페이스는 선언된 패키지에 속함

→ 원칙적으로는 클래스명과 구분을 위해 소문자로 작성

→ 패키지 지정하지 않을 경우 기본적으로 자바에서 이름없는 패키지를 제공

2. import 키워드


import문의 역할

: 컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공.

컴파일 시에 컴파일러는 import문을 통해 소스파일에 사용된 클래스들의 패키지를 알아낸 후 모든 클래스이름 앞에 패키지명을 붙여줌

(→ 클래스 코드 작성시 클래스이름에서 패지지명 생략 가능)

import 패키지명.클래스명;
or
import 패키지명.*; // 지정된 패키지에 속하는 모든 클래스를 패키지명 없이 사용 가능.

→ 모든 소스파일에서 import문은 패키지문 다음 && 클래스 선언문 이전에 위치

(package문 > import문 > 클래스 선언)

→ 한 소스파일에서 여러번 선언 가능

1)가능

import java.util.Calendar;
import java.util.Date;
import java.util.ArrayList;

or 

import java.util.*;

2) 불가능
import java.util.*;
import java.text.*;

!= import java.*;
// import문에서 클래스의 이름 대신 * 사용. 그러나 하위 패키지의 클래스까지 포함하는건 아님.

** System과 String 같은 java.lang 패키지의 클래스들은 패지키명 없이 사용 가능

→ java.lang패키지는 매우 빈번히 사용되는 중요한 클래스들이 속한 패키지이기 때문에 import문으로 지정하지 않아도 됨.

Static import문

static import문 사용하면 static 멤버 호출할때 클래스 이름 생략 가능.

import static java.lang.Integer.*; // Integer클래스의 모든 static 메서드
import static java.lang.Math.random; //
import static java.lang.System.out; //system.out을 out만으로 참조 가능

out.prinln(random());

//System.out.printlin(Math.random()) 대신 위의 코드로 간결하게 작성 가능.

3. 클래스패스


클래스패스란?

컴파일러나 JVM 등이 클래스의 위치를 찾는데 사용되는 경로.

(JVM이 프로그램을 실행할 때, 클래스 파일을 찾는데 기준이 되는 파일 경로)

→ 소스파일에 지정된 경로를 통해 패키지의 위치를 찾아서 클래스파일을 생성함.

만일 지정된 패키지와 일치하는 디렉토리가 존재하지 않는다면 자동적으로 생성.

출처: 그림 출처 - 알짜배기 프로그래머 블로그

→ 클래스 로더는 JVM에 바이트 코드(.class)를 불러오는 역할

→ JVM의 클래스 로더는 JVM이 시작될 때 CLASSPATH 환경 변수를 호출하여 CLASSPATH 환경 변수에 설정되어 있는 디렉토리를 파악.

→ 기본적으로는 java 명령어가 실행된 위치를 default class path로 갖지만 CLASSPATH 환경 변수 설정이나 커맨드 라인에서 java 명령어에 -classpath나 -cp 명령을 이용해 설정 가능.

결론: 자바 소스코드를 컴파일해서 바이트코드로 변환후 이 바이트코드에 포함된 명령을 사용하기위해 해당 파일을 찾아야하고 그 경로를 찾기 위해 classpath 환경 변수에 저장된 클래스패스를 사용.

4. CLASSPATH 환경변수


Classpath 환경변수란?

.class 파일을 찾기 위한 경로가 저장되어 있는 환경 변수

.class 파일이 포함된 디렉토리와 파일을 세미콜론(;)으로 구분한 목록

→ java runtime은 이 CLASSPATH 환경 변수에 저장된 경로를 모두 검색해서 특정 클래스에 대한 코드가 포함된 .class 파일을 찾음.

→찾으려는 클래스 코드가 포함된 .class 파일을 찾으면 해당 파일을 사용

5.classpath 옵션


커맨드 라인에서 java 명령어를 실행할 때 -classpath나 -cp를 붙여 클래스패스를 특정할 수 있음

Use classpath or cp

C:> sdkTool -classpath classpath1;classpath2...

Use set CLASSPATH

C:> set CLASSPATH=classpath1;classpath2...

  1. sdkTool
    • javajavacjavadoc과 같은 커맨드 라인 툴이 해당
  2. classpath1;classpath2
    • .jar.zip.class 파일이 위치하는 클래스패스를 뜻함
    • 각 클래스패스는 파일 이름이나 디렉토리 이름으로 끝나야함
  3. 다양한 클래스패스를 갖는다면 세미콜론(;)으로 구분
  4. default class path는 현재 디렉토리를 가리킴
    • 다만, 다른 클래스 패스를 추가하려고 classpath 옵션이나 set을 사용한다면 .을 맨 앞에 붙여 현재 위치를 클래스패스 목록에 추가할 수 있음

6.접근지시자


제어자란?

클래스, 변수 또는 메서드의 선언부에 함께 사용되어 부가적인 의미 부여.

-접근제어자: public, protected, default, private

-그외: static, final, abstract, native, transient, synchronized, volatile, strictfp

→ 하나의 대상에 대해서 여러개의 제어자를 조합해서 사용 가능.

(단, 접근 제어자는 4가지중 한개만 사용 가능)

static -클래스의 공통적인

→ 인스턴스에 관계없이 같은 값. 하나의 변수를 모든 인스턴스가 공유.

→ 인스턴스 생성하지 않고 사용 가능

→ 멤버변수, 메서드, 초기화 블럭에 사용 가능

→ 클래스가 메모리에 로드될 때 생성됨.

→ static 메서드 내에서는 인스턴스멤버들을 직접 사용 불가

abstract- 추상의, 미완의

→ 메서드의 선언부만 작성하고 실제 수행내용은 구현하지 않은 추상 메서드를 선언하는데 사용

→ 클래스 앞에 붙을 경우 클래스내에 추상 메서드가 선언되어 있음을 의미.

→ 추상 클래스는 미완이므로 인스턴스 생성 불가.

→ 상속받아서 일부 원하는 메서드만 오버라이딩 가능하다는 장점.

접근 제어자란?

멤버 또는 클래스에 사용되어, 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할

→클래스, 멤버변수, 메서드, 생성자에 사용 가능

→ 클래스 내부에 선언된 데이터 보호 목적 ( 캡슐화), 내부 작업을 위해 임시로 사용되는 변수나 부분작업을 내부에 감추기 위해서(복잡성 줄임)

private: 같은 클래스 내에서만 접근 가능.

default: 같은 패키지 내에서만 접근 가능.

protected: 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근 가능.

public: 접근 제한 없음.

→ public > protected > default > private 순

→private 멤버변수는 getter와 setter를 통해 접근.

-생성자의 접근제어자

→ 인스턴스 생성을 제한할 수 있음. (생성자를 private으로 지정하면 외부에서 생성자에 접근 불가. 그러나 클래스 내부에서는 인스턴스 생성 가능)

class Singleton{
	private static Singleton s = new Singleton(); // getInstance에서 사용될 수 있도록 인스턴스가 미리 생성되어야 하므로 static 
	private Singleton() {} // private 생성자

	public static Singleton getInstance(){ //인스턴스 생성하지 않고도 호출할 수 있어야 하므로 static. 외부에서 해당 인스턴스 사용 가능하도록 public.
			return s;
		}

}

→ 생성자를 통해 직접 인스턴스 생성 제한하고 public 메서드를 통해 인스턴스에 접근하게 함으로써 인스턴스의 개수 제한 가능.

** 제어자의 조합시 주의 사항

  • 메서드에 static 과 abstract 동시 사용 불가(static은 몸통이 있는 메서드에만 사용 가능)
  • 클래스에 abstract과 final 동시 사용 불가(의미 모순)
  • abstract메서드의 접근 제어자가 private일 수 없음

(abstract는 자손 클래스에서 구현해야하는데 private이면 자손 클래스에서 접근 불가능)

  • 메서드에 private과 final 같이 사용할 필요 없음. (private은 오버라이딩될 수 없으므로)
profile
우당탕탕 개발 일기

0개의 댓글