package 키워드
package는 클래스를 구분짓는 폴더와 같은 개념이라고 생각하면 됩니다.
package 특징
- 자바는 패키지의 가장 상위 디렉토리(root)에서 실행되야 한다는 약속이 있기에 해당 패키지에서 컴파일을 진행하지 않습니다.
- 소스에 가장 첫 줄에 있어야 하고, 패키지 선언은 소스 하나에 하나만 존재해야 합니다.
- 패키지 이름은 java로 시작해서는 안됩니다.
- 모든 클래스에는 정의된 클래스 이름과 패키지 이름이 있습니다. 이 둘을 합쳐야 완전한 한 클래스를 표현했다고 할 수 있으며, 이를 FQCN(Fully Qualified Class Name)이라고 부릅니다.
한 예시로 String 클래스의 패키지는 java.lang이며, FQCN은 java.lang.String이 됩니다.
package 이름 지정 규칙
패키지 시작이름 | 내용 |
---|---|
java | 자바 기본 패키지(Java vendor 개발) |
javax | 자바 확장 패키지(Java vendor 개발) |
org | 일반적으로 비영리단체 (오픈소스) 패키지 |
com | 일반적으로 영리단체(회사) 패키지 |
package 이름 명명 규칙
패키지 이름은 모두 소문자여야 합니다.
자바의 예약어를 사용하면 안됩니다. (예를 들어, int, static은 사용 X)
개발 패키지 표준은 상황에 맞게 정하면 됩니다.
Built-in Package
자바는 개발자들이 사용할 수 있도록 여러 많은 패키지 및 클래스를 제공합니다.
가장 자주 쓰이는 패키지로 java.lang과 java.util이 있습니다.
java.lang은 패키지는 기본적인 것들이기에 import로 불러오지 않아도 자바가 알아서 java.lang의 클래스를 불러옵니다.
import java.lang.String;
import java.lang.System;
public class Main{
public static void main(String[] args){
String str = "this is from java.lang.String";
System.out.println(str);
}
}
import 키워드
import 패키지명.클래스명
다른 패키지명에 있는 클래스를 찾지 못할 때 사용합니다.
패키지에 다수의 클래스를 import
하는 경우 import 패키지명.*
처럼 import 할 수 있습니다.
public class SubStatic{
public static final String CLASS_NAME = "SubStatic";
public static void subStaticMethod(){
System.out.println("subStaticMethod is called");
}
}
public class Package{
Package(){}
public static void main(String[] args){
Sub sub = new Sub();
sub.subClassMethod();
System.out.println("--static case--");
System.out.println(CLASS_NAME);
subStaticMethod();
}
}
import static
의 경우, static한 변수(클래스 변수)와 static한 메서드를 사용하고자 할 때 용이합니다.
만약 static이 없다면 클래스.함수
, 클래스.변수
형태로 사용해야 합니다.
앞서 언급했듯이 import하지 않아도 되는 패키지는 java.lang 패키지에 있는 패키지입니다.
또한 같은 패키지는 import를 할 필요가 없습니다.
접근 제어자
접근 제어자는 클래스, 메소드, 인스턴스 및 클래스 변수를 선언할 때 사용됩니다. 자바에선 사용하는 접근 제어자는 public, protected, package-private(접근 제어자 없음), private로 총 4가지 입니다.
public class AccessModifier{
public void publicMehtod(){}
protected void protectedMethod(){}
void packagePrivateMethod(){}
private void privateMethod(){}
}
public class AccessCall{
public static void main(String[] args){
AccessModifier accessModifier = new AccessModifier();
accessModifier.publicMehtod();
accessModifier.protectedMethod(); // 에러 발생
accessModifier.packagePrivateMethod(); // 에러 발생
accessModifier.privateMethod(); // 에러 발생
}
}
public
누구나 접근이 가능합니다.
protected
같은 패키지에 있거나 상속 받은 경우 사용할 수 있습니다.
package-private
아무 접근제어자를 적어주지 않는 경우이며, package-private라 불립니다. 같은 패키지 내에서 접근이 가능합니다.
private
해당 클래스내에서만 접근이 가능합니다.
public class PublicClass{
public static void main(String[] args){
System.out.println("public class");
}
}
class PublicSecondClass{
}
또 다른 예시로 하나의 소스 파일 내에 2개 이상의 클래스를 정의하는 경우, 파일 이름과 같은 클래스명을 제외한 클래스는 package private여서 같은 패키지 내에 있는 클래스들만 이 클래스의 객체를 생성하고, 이용할 수 있습니다.
물론 이 방법은 권장되는 방법은 아닙니다.
클래스패스
클래스 패스는 클래스를 찾기 위한 경로입니다.
JVM이 프로그램을 실행할 때 클래스 파일을 찾는 데 클래스 패스를 사용하게 됩니다.
즉, JVM은 CLASSPATH의 경로를 확인하여 라이브러리 클래스들의 위치를 참조하게 됩니다. 그러나 J2 JDK버전부터는 /jre/lib/ext 폴더에 필요한 클래스 라이브러리들을 복사해 놓으면 사용 가능하여 특별한 경우가 아니면 설정을 하지 않습니다.
소스 코드(.java로 끝나는 파일)를 컴파일하면 소스 코드가 "바이트 코드"로 변환됩니다.
java runtime(java 또는 jre)으로 이 .class 파일에 포함된 명령을 실행하려면, 이 파일을 찾을 수 있어야 합니다.
.class 파일을 찾을 때, classpath에 지정된 경로를 사용합니다.
classpath를 지정하기 위한 2가지 방법이 있습니다.
- CLASSPATH 환경 변수를 사용합니다.
- java runtime에 -classpath 옵션을 사용합니다.
CLASSPATH 환경변수
CLASSPATH=.;C:\Program Files\Java\jdk1.8..
컴퓨터 시스템 변수 설정을 통해 지정할 수 있습니다.
JVM이 시작될 때 JVM의 클래스 로더는 이 환경 변수를 호출합니다. 그래서 환경 변수에 설정되어 있는 디렉토리가 호출되면 그 디렉토리에 있는 클래스들을 먼저 JVM에 로드합니다.
java runtime에 -classpath 옵션 사용
javac <options> <souce files>
컴파일러가 컴파일 혹은 필요로 하는 참조할 클래스 파일들을 찾기 위해서 컴파일시 파일 경로를 지정해주는 옵션을 말합니다.
Hello.java
파일이 C:/java
디렉터리에 존재하고, 필요한 클래스 파일들이 C:/java/Engclasses
에 위치한다면, javac -classpath C:/java/Engclasses;C:/java/Hello.java
와 같이 ;로 구분해줄 수 있습니다.
(.
은 현 디렉토리, ..
은 현 디렉토리에서 상위 디렉토리를 의미합니다.)
또한 classpath 대신 단축어인 cp를 사용해도 됩니다.