Package
비슷한 기능을 하는 클래스들을 모아 둔 폴더.
물리적으로 클래스들을 모아둔다.
클래스들을 계층구조로 관리하는데 유용하다.
접근지시자
인터페이스, 클래스, 함수, 멤버변수 등을 선언 시 접근지시자로 접근 범위를 제한시킬 수 있다.
접근지시자 | 같은 클래스 내 | 같은 패키지 내 | 서브클래스 내 | import한 클래스 내 |
private | O | X | X | X |
package private | O | O | X | X |
protected | O | O | O | X |
public | O | O | O | O |
package 키워드
package 키워드로 패키지를 지정하지 않으면 default package(unnamed package)에 들어간다.
현재 자바 클래스를 특정 패키지로 지정하고 싶으면 package 키워드를 사용한다.
코드의 최상단에 위치한다.
naming 규칙
- 소문자로 작성한다.
- 패키지명은 고유해야 한다.
- 회사에서는 도메인의 역순으로 패키지명을 짓는다. ex) junit 도메인 : junit.org / package명 : org.junit.이름.**;
- Java 언어의 패키지는 java or javax
- java 키워드나 숫자로 시작하는 이름은 패키지명으로 사용불가능하다. 키워드를 패키지명으로 사용하고 싶은경우 언더바(_)를 사용한다.
불가능 : com.1name / interface.name
가능 : com.na1me / com._1name / _interface.name / interface_.name
예시
// java
package hello.car;
public class Wheel {}
// bytecode
public class hello.car.Wheel { // ... }
bytecode에서는 클래스이름에 패키지 이름이 패키지명.클래스이름으로 들어간다.
import 키워드
public class HelloJava {
void print() {
hello.A.Car a = new hello.A.Car();
}
}
다른 패키지에 있는 클래스나 인터페이스를 사용하려면 위 코드와 같이 패키지이름.클래스이름 으로 사용할 수 있다.
그러나 항상 코드에 "패키지이름.클래스이름" 을 반복한다면 코드가 더러워져 가독성이 떨어진다.
import hello.A.Car
public class HelloJava {
void print() {
Car a = new Car();
}
}
그럴때 위와 같이 다른패키지의 클래스를 import 키워드로 임포트해주면 코드상에서 패키지명을 생략할 수 있다.
import 패키지이름.클래스이름
import 패키지이름.* // 패키지의 모든 클래스들을 import 해오고 싶은 경우
default package인 클래스들은 특정 패키지가 없어서 임포트를 할 수 없다.
import hello.A.Car;
public class HelloJava {
void print() {
Car a = new Car();
hello.B.Car b = new hello.B.Car();
}
}
만약 서로 다른 패키지에 동일한 이름의 클래스가 있고 이를 또다른 패키지에서 둘 다 사용하고 싶은 경우,
구분할 수 있는 방법이 패키지밖에 없으므로 둘 중 하나는 패키지명까지 포함하여 코드상 명시해주어야 한다.
java.lang 패키지(기본타입 등)에 있는 클래스, 인터페이스들은 임포트없이 사용가능하다.
컴파일 -sourcepath 옵션
소스파일 경로를 지정한다.
package member;
public class Member {}
import java.util.List;
import member.Member;
public class Subject {
List<Member> members;
public static void main(String[] args) {
System.out.println("subject");
}
}
Member, Subject 자바 파일을 만들고 위와 같은 폴더 구조를 가진다고 하자. (out 폴더는 비어있음)
$ javac src/Subject.java
study 폴더 위치에서 위와 같은 명령어로 컴파일해보면
member 패키지를 찾을 수 없어 위와 같은 에러가 발생한다.
$ javac -sourcepath src src/Subject.java
-sourcepath 옵션으로 소스파일 경로의 최상위 위치(src)를 지정해주면 컴파일러는 컴파일 시 자바파일을 해당 폴더에서 찾는다.
컴파일 결과 각 패키지 경로에 .class 파일이 생긴다.
컴파일 -d 옵션
컴파일 결과물 저장 디렉터리 설정.
package test;
public class A {}
javac -d(directory) 옵션을 줘서 클래스파일의 루트 디렉터리 위치를 지정해주면 자바 파일에 명시한 패키지 폴더에 맞게 클래스파일들이 생성된다.
만약 -d 옵션을 주지 않으면 자바파일과 같은 위치에 생성된다.
$ javac -d out -sourcepath src src/Subject.java
보통 -sourcepath 옵션과 -d 옵션을 같이 줘서 컴파일 결과물들을 하나의 폴더로 모아둔다.
클래스패스 (classpath)
클래스패스란 자바 실행 시 참고할 클래스들의 위치를 의미한다.
만일 클래스들이 분산되어 있다면 클래스패스를 지정해줘야 한다.
.:lib
클래스패스를 위와 같이 설정해주었다면
현재 디렉터리(.)에서 원하는 클래스를 찾고 없는 경우 다음 경로(: 는 구분자)에 있는 경로(현재 경로의 lib 폴더)에서 클래스들을 찾는다.
-classpath 옵션
$ java -classpath ".:lib" 클래스파일이름
자바 파일 실행시 -classpath 옵션으로 클래스패스를 지정할 수 있다.
CLASSPATH 환경변수
매번 자바 실행 시 -classpath 옵션을 주기 싫다면 CLASSPATH 환경변수로 지정할 수 있다.
한 번 지정해두면 자바 실행 시 -classpath 옵션을 주지 않아도 해당 값을 참고하여 클래스패스를 지정해준다.
mac 클래스패스 설정
vi ~/.bash_profile
편집 모드로 열기.
// add
export CLASSPATH=.:lib
환경변수 추가후 :wq 명령어로 저장후종료.
참고
docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
'JAVA' 카테고리의 다른 글
[java] Enum (0) | 2021.01.30 |
---|---|
[Java] 멀티쓰레드 (0) | 2021.01.23 |
[Java] 데이터, 변수, 배열 (0) | 2020.12.27 |
[Java] JVM (0) | 2020.12.27 |
[Java] 상속(Inheritance) (0) | 2020.12.24 |
댓글