Package
패키지
패키지
*.java 구성
1. package문
2. import문
3. 클래스 선언
package
패키지는 클래스(인터페이스 포함)의 묶음이다. 서로 관련된 클래스들끼리 그룹 단위로 묶어 놓아 클래스를 효율적으로 관리할 수 있다. (패키지는 물리적인 디렉토리임)
서로 다른 패키지에 있다면 같은 이름의 클래스를 사용하는 것이 가능하다.
클래스의 실제 이름 즉, full name 은 패키지명 + 클래스이름 이다.
예를들어, String 클래스의 full name은 java.lang.String
이다.
💡 하나의 소스파일에는 첫 번째 문장으로 단 한 번의 패키지 선언만을 허용한다.
💡 모든 클래스는 반드시 하나의 패키지에 속해야 한다. (java 기본제공 - unnamed package)
💡 패키지는 점(.)을 구분자로 계층구조로 구성할 수 있다.
💡 패키지는 물리적으로 클래스 파일을 포함하는 하나의 디렉토리이다.
패키지 선언
package 패키지명;
패키지 선언문은 반드시 주석과 공백을 제외한 첫 번째 문장이어야 한다. 하나의 소스파일에 단 한번만 선언될 수 있으며 해당 소스파일에 포함된 모든 클래스나 인터페이스는 선언된 패키지에 속하게 된다.
패키지명은 대소문자를 모두 허용 하지만 클래스명과 쉽게 구분하기 위해서 소문자로 하는 것을 원칙 으로 하고있다.
- 패키지명 예시
- com.회사이름.프로그램이름 (
com.naver.goodapp
) - com.회사이름.플랫폼.프로그램이름 (
com.naver.android.goodapp
) - …
- com.회사이름.프로그램이름 (
import
다른 패키지에 있는 클래스를 사용하려면 패키지명이 포함된 클래스 이름을 사용해야 한다. 그러나 매번 full name을 붙여서 작성하기는 여간 귀찮은 일이 아니다. 이 때, import
키워드를 활용하여 사용하고자 하는 클래스의 패키지를 미리 명시해주면 패키지명은 생략하고 클래스 이름으로 다른 패키지에 있는 클래스를 사용할 수 있다.
즉, import문의 역할은 컴파일러에게 소스파일에 사용된 클래스의 패키지에 대한 정보를 제공하는 것이다. 컴파일시 컴파일러는 import
문을 통해 사용된 클래스패키지를 알아낸 다음 모든 클래스 이름 앞에 패키지명을 붙여준다.
import 선언
package 패키지명;
import 패키지명.클래스명;
import 패키지명.*;
같은 패키지에서 여러 클래스가 사용될 때 import 패키지명.*
형식으로 작성하면 여러 클래스를 일일이 적어줄 필요 없이 지정된 패키지에 속하는 모든 클래스를 패키지명 없이 사용할 수 있다.
import문은 package문 다음에, 클래스 선언문 이전에 위치해야 하고 여러 번 선언할 수 있다.
.*
의형식을 사용하는 경우 *
은 클래스의 이름 대신 사용하는 것이므로 다음과 같은 코드는 작성 할 수 없다.
import java.util.*;
import java.text.*;
import java.*; // 불가능
만약 intellij 같은 툴을 사용한다면 Alt + Enter
단축키로 import를 할 수 있다.
java.lang
패키지는 별도의 import 없이 사용이 가능하다.
static import
패키지, 클래스명 없이 접근 가능하게 해주는 import 문으로 JDK 1.5부터 지원한다.
예를들어,
import java.lang.Math.abs;
int value = Math.abs(-3);
기본 import문을 사용하면 패키지명 없이 클래스명.메소드명 으로 사용할 수 있지만
import static java.lang.Math.abs;
int value = abs(-3);
static import문을 사용하면 패키지명, 클래스명 없이 메소드명만으로도 사용이 가능하다.
클래스패스
말 그대로 클래스를 찾기 위한 경로로, JVM이 프로그램을 실행할 때 클래스파일을 찾는데 기준이 되는 파일 경로이다.
classpath 지정하는 방법
-
java -classpath 옵션 사용 (-classpath = -cp)
다음코드를 temp 디렉토리에 저장한다.
public class ClasspathTest { public static void main(String[] args) { Test test = new Test(); test.print(); } } class Test { public void print() { System.out.println("Hello, world"); } }
그런다음
javac[ClasspathTest.java](http://classpathtest.java)
명령어로 컴파일을 하면 다음과같이 클래스파일이 생긴다.그리고 Test.class 파일을 lib 폴더 에 옮긴다.
그리고 java 명령어로 ClasspathTest.java를 실행하면 다음과 같은 에러가 나오게 된다.
Exception in thread "main" java.lang.NoClassDefFoundError: Test at ClasspathTest.main(ClasspathTest.java:3) Caused by: java.lang.ClassNotFoundException: Test at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522) ... 1 more
에러를 찬찬히 보게되면 Test.class 파일이 현재 디렉터리에 존재하지 않기 때문에 찾을 수 없다는 메시지이다. → 클래스패스를 지정해주어야 한다.
java -classpath ".;lib" ClasspathTest // Widow java -classpath ".:lib" ClasspathTest // linux
이렇게 -classpath 옵션을 이용하여 현재디렉토리와 lib 폴더를 지정해주면 실행할 때 사용할 클래스들의 위치를 jvm이 알 수 있어 오류가 나지 않는다.
.
: 현재 디렉터리에서 클래스를 찾는다.;
or:
: 경로와 경로를 구분해주는 구분자
-
CLASSPATH 환경변수 사용
1번방법으로 매번 classpath를 지정하기는 매우 귀찮은 일이다. 컴퓨터 시스템 변수 설정을 통해 그 번거로움을 없앨 수 있다.
JVM의 클래스 로더는 여기에서 설정한 환경변수를 호출하고 환경변수에 저장되어 있는 디렉토리에 있는 클래스들을 먼저 JVM에 로드하게 된다. 그러므로 CLASSPATH 환경변수에는 필수 클래스들이 위치한 디렉토리를 등록하는 것이 좋다.
- 환경변수
- 사용자변수 : OS 내 사용자별로 다르게 설정 가능한 환경변수
- 시스템변수 : 시스템 전체에 모두 적용되는 환경변수
-
윈도우
변수 값 항목에 CLASSPATH 위치를 지정해주면 된다.
-
리눅스 (Ubuntu)
/etc/environment 파일을 수정하면 된다.
JAVA_HOME=... CLASSPATH=.:...
윈도우는 구분자로
;
를 사용하지만 리눅스에서는:
로 구분한다는 것에 주의하면서 수정한다.수정후
source /etc/environment
하게 되면 적용이 완료된다.
- 환경변수
접근지시자 (Access Modifier)
변수, 메소드, 클래스 선언시 사용하며 해당 변수, 메소드, 클래스의 접근을 제한하는 역할의 키워드이다.
선언된 데이터를 외부로부터 보호해주기 위한 것으로 캡슐화(Encapsulation)와 정보은닉의 특성을 구현할 수 있게 해준다.
또한, 생략이 가능하며 생략시 default 를 의미한다.
public
: 같은 프로젝트면 어디에서든 접근 가능default
(package private) : 같은 패키지 안에서는 어디에서든 접근 가능private
: 같은 클래스 안에서는 어디에서든 접근 가능protected
: 상속 관계이면 어디에서나 접근 가능
접근제어자를 사용하면 클래스 외부에서의 직접적인 접근을 허용하지 않는 멤버를 설정하여 정보은닉을 구체화 할 수 있다.
private
외부에 공개되지 않으며 외부에서 직접 접근할 수 없다. public 메소드를 통해서만 접근할 수 있다. 주로 클래스 내부의 세부적인 동작을 구현하는데 사용된다.
http://www.tcpschool.com/java/java_modifier_accessModifier
public
외부로 공개되며 해당 객체를 사용하는 프로그램 어디에서나 직접 접근할 수 있다.
http://www.tcpschool.com/java/java_modifier_accessModifier
default (package private)
접근제어의 기본값으로 접근제어자가 지정되지 않으면 자동적으로 default 접근제어를 가지게 된다. 같은 클래스 멤버와 같은 패키지에 속하는 멤버에서만 접근 가능하다.
http://www.tcpschool.com/java/java_modifier_accessModifier
protected
protected로 설정된 멤버는 부모 클래스에 대해서는 public 멤버처럼 취급되며, 외부에서는 private 멤버처럼 취급된다.
- 이 멤버를 선언한 클래스의 멤버
- 이 멤버를 선언한 클래스가 속한 패키지의 멤버
- 이 멤버를 선언한 클래스를 상속받은 자식 클래스의 멤버
위에 기재한 멤버들은 protected 멤버에 접근할 수 있다.