package
클래스의 묶음, 클래스를 구분짓는 폴더 개념으로 생각하면 좋을 것 같다
클래스를 패키지로 구분짓는 이유는 이 체계를 유지함으로써 다른 개발자가 개발한 라이브러리의 클래스와 이름 충돌을 피할 수 있다
jdk내부를 살펴서 클래스를 찾을려했지만 아쉽게도 이제는 jdk- jre - lib - rt 구성으로 되어있는데
이때 rt는 Java Runtime Environment이다. rt에서 필요한 패키지를 호출하는 식으로 이루어져있다
(ex. 사용자가 java.util패키지를 호출하면 JVM이 rt.jar 내부에서 해당 피키지를 찾는다)
패키지는 규칙이 있다
- 패키지 이름과 위치한 폴더의 이름이 같아야 한다
- 패키지 이름을 java로 시작하면 안된다
- 모든 클레스에는 정의된 클래스 이름과 패키지 이름 이 있다. 따라서 이 둘을 합쳐와 완전하게 한 클래스를 표현한다고 할 수있으며 FQCN(Fully Qualified Class Name)이라고 한다
(ex. String 클래스의 패키지는 java.lang이며 FQCN은 java.lang.String이 된다)
패키지 이름 지정 규칙
- java: 자바 기본 패키지(Java vendor개발)
- javax: 자바 확장 패키지(Java vendor 개발)
- org: 일반적으로 비영리 단체(오픈소스) 패키지
- com: 영리단체(회사) 패키지
패키지 이름 명명 규칙
- 패키지 이름은 모두 소문자여야 한다(ex. java.lang, java.util)
- 자바의 예약어를 사용하면 안된다.(ex. int, static)
- 개발 패키지 표준은 정하는 것에 따라 지정하면 된다. 패키지 이름에 대한 규칙이나
패턴은 프로젝트 또는 조직마다 다를 수 있다는 의미이다.
빌트-인 패키지(Built-in Package)
자바는 개발자들이 사용할 수 있도록 여러 패키지 및 클래스를 제공한다
위 이미지에서 Java Standard libraries를 참고하면 된다
- java.lang: language suppoart 클래스들을 포함사는 패키지이다
- 프리미티브 타입이나 수학 연산의 정의가 되는 클래스들
- 자동으로 import되기 때문에 해당 패키지의 클래스를 바로 사용할 수 있다.
- java.util : 자료구조 구현을 위한 유틸리티 클래스를 포함하는 패키지이다
- java.io : 입출력 기능을 지원하는 클래스들을 포함하는 패키지이다
- java.applet : Applets을 생성하기 위한 클래스들을 포함하는 패키지이다
- java.awt: GUI 컴포넌트를 구현하기 위한 클래스들을 포함하는 패키지이다
- java.net: 네트워킹 기능을 지원하기 위한 클래스를 포함하는 패키지이다
import
같은 패키지에 속하는 클래스들은 서로 아무 조건없이 사용할 수 있지만, 다른 패키지에 속하는 클래스를
사용하려면 2가지 방법 중 하나를 선택해야한다. 그중 하나가 import이다
1. 패키지와 클래스를 모두 기술하는 방법
사용방법은 아래와 같다
위에 코드 예시로만 보면 크게 불편해 보이지는 않지만 계속해서 사용해야할 클래스가 많다면
써야할 코드가 많아지고 가독성이 불편해진다
2. import 문 사용
사용하고자 하는 패키지를 import문으로 선언하고, 클래스를 사용할때는 패키지를 생략한다
위의 FQCN 사용의 단점을 보완해준다
1,2번 방법을 보다가 느낀게 그러면 import문은 장점만 있는것인가? 찾아보니
불필요한 클래스까지 가져올 수 있으므로 약간의 성능저하가 있을 수도 있다고 한다. 허나 이건 과거의 컴파일러
이야기이고 현대의 컴파일러는 이러한 영향을 최소화하도록 최적화가 되어있다.
읽다보니 궁금즘이 또 생겼다
현대의 컴파일러는 어떻게 저런 최적화를 할 수 있을까?
일단은 컴파일러의 내부 작동방식을 간략하게알아야 한다
컴파일러의 내부 작동 방식
파싱 -> 중간코드 생성 -> 최적화 -> 코드 생성
최적화 단계에서 컴파일러는 다양한 분석기법을 사용하여 필요하지 않는 클래스를 구분한다
- 데이터 흐름 분석
- 값 번역 분석
- 사용 전/후 분석
- 루프 최적화
너무 자세하게 설명하는건 이 내용과 동떨어진거같아 여기서 멈추겠다
import문 주의점
import문으로 지정된 패키지의 하위 패키지는 import 대상이 아니다.
그렇다보니 하위 패키지의 클래스를 이용하고 싶다면 import문을 하나 더 작성해야 한다.
그러므로 import를 하나 더 해줘야 한다
한가지 추가 주의할점은 패키지가 다른데 클래스 이름이 동일한 경우이다
만일 두개의 패키지가 다 import되어있고 각각의 클래스를 사용해야한다면 정확한 패키지 이름과 이름 전체를 기술해야한다
static import
일반적인 import와 다르게 메소드나 변수를 패키지, 클래스명 없이 접근 간으하게 해준다
예를들어 Math클래스의 Math.max(int a, int b) 메소드를 예시로 들겠다
원래 사용법
static import 사용
장점
편리해지는 부분이 많은데 특히나 테스트 프레임 워크 JUnit을 사용할때 더 코드를 간략하게 사용할 수 있다
클래스패스
말 그대로 클래스를 찾기 위한 경로이다. 더 자세히 설명하면 JVM이 클래스 파일을 찾는 경로를 지정하는 설정이다.
밑에 그림을 참고해서 설명해보면 JVM은 클래스 로더를 사용하여 자바 클래스 라이브러리에서 필요한 클래스를 검색하고
메모리에 로드한다. 이 과정에서 Class path는 로드할 클래스 파일을 찾는 경로를 결정하는 역할을 한다.
자바에는 3가지의 Class Loader가 존재한다
- Bootsrap Class Loader
- JVM내부에 있는 클래스 로더로, Java의 기본 클래스들과 라이브러리들을 로딩한다
- jre/lib/rt.jar에 담긴 JDK클래스 파일을 로딩한다
- Extension Class Loader
- 확장 라이브러리들을 로드하는 역할을 한다
- Sysetm Class Loader
- 사용자가 만든 Class를 메모리에 올리는 역할을 한다
- 그때 classpath 기준으로 클래스들을 로드한다
이 classpath를 지정하기 위한 두가지 방법이 있다
- CLASSPATH 환경변수 사용
- java runtime 에 -classpath 옵션 사용
CLASSPATH 환경변수
컴퓨터 시스템 변수 설정을 통해 지정할 수 있다.
이렇게 지정하면 JVM이 시작될때 JVM의 클래스 로더는 이 환경 변수를 호출한다. 그에 따라 환경 변수에 설정되어
있는 디렉토리가 호출되면 그 디렉토리에 있는 클래스들을 먼저 JVM에 로드한다. 그러므로 CLASSPATH 환경 변수에는
모든 클래스가 아닌 필수 클래스들이 위치한 디렉토리를 등록해야한다.
방법은 다음과 같다
-classpath 옵션
위에 환경변수랑 다른 방법으로 java runtime에 -classpath 옵션을 사용해서 지정하는 방법이다.
이 방법은 클래스 패스를 성정하여 JVM이 클래스 파일을 찾는 경로를 지정할 수 있다.
방법은 다음과 같다
필요한 클래스 파일이 subClass 폴더에 있다면 이렇게 하면 된다
자바 소스 코드를 컴파일하는 명령어
javac -classpath C:\myclass\mysubclass C:\myclass\ClassPath.java
생성된 클래스 파일을 실행하는 명령어
java -classpath C:\myclass\mysubclass; C:\myclass ClassPath
접근 제어자
멤버 또는 클래스에 사용되어, 해당하는 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할 수행한다
접근제어자: public, protected, default(지정 안되어있으면 자동 제어자), private
접근 범위
해당 클래스 내 | 같은 패키지 내 | 상속받은 클래스 | import한 클래스 | |
public | O | O | O | O |
protected | O | O | O | X |
default | O | O | X | X |
private | O | X | X | X |
사용 이유
- 외부로부터 데이터를 보호하기 위해서
- 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해서
제어자 조합 주의해야할점
- abstract메서드의 접근 제어자가 private일 수 없다
- abstract 메서드는 자손클래스에 구현해줄려고 사용하는것인데 접근 제어자가 private이면 자손클래스에서
접근 불가능하다
- abstract 메서드는 자손클래스에 구현해줄려고 사용하는것인데 접근 제어자가 private이면 자손클래스에서
- 메서드에 private과 final을 같이 사용할 필요는 없다
- 접근 제어자가 private인 메서드는 오버라이딩 될 수 없기 때문이다. 따라서 두개의 의미가 같기에 하나만 사용해주면 된다
참고
자바의 정석(저자 남궁성)
https://kils-log-of-develop.tistory.com/430
https://five-cosmos-fb9.notion.site/ed8e346f88f54849a06ff968b1877ca5
'자바(Java)' 카테고리의 다른 글
[자바] 자바 예외처리 (0) | 2023.09.14 |
---|---|
[자바] 자바 인터페이스 (0) | 2023.09.08 |
[자바]자바 상속, 다이나믹&더블 메소드 디스패치 (0) | 2023.08.21 |
[자바] 자바 클래스 (0) | 2023.08.14 |
[자바] HashSet 중복값 처리 과정, 배열로 변경하는 법 (0) | 2023.08.08 |