목표
자바의 패키지에 대해 학습하세요.
학습할 것 (필수)
- package 키워드
- import 키워드
- 클래스패스
- CLASSPATH 환경변수
- -classpath 옵션
- 접근지시자
1) package 키워드
패키지란 클래스, 인터페이스들 묶음이라고 할 수 있다. 패키지를 사용하는 이유는 연관된 클래스, 인터페이스끼리 묶어 효율적으로 관리하고자 하는 데 있다.
특징
1. 클래스의 첫 번째 문장에 그 클래스가 속한 패키지를 선언한다.
2. 모든 클래스들은 모두 하나의 패키지에 속해야 한다.
3. 패키지는 도트(.) 연산자를 이용해 패키지 계층구조를 구분한다.
4. 패키지도 물리적 클래스 파일(.class)을 포함하는 하나의 디렉토리이다.
5. 패키지를 선언하지 없으면 자바에서 기본적으로 제공하는 이름 없는 패키지(unnamed package)에 속하게 된다.
6. 서브 패키지는 패키지의 패키지를 의미한다.
7. 디폴트 패키지는 import 시킬 수 없다.
어떻게 사용하는지?
소스파일 제일 위에 아래 문장을 넣어 준다.
package 패키지명;
어떤 특정 패키지에 속한 클래스를 사용하고 싶으면 패키지의 full경로를 적어 사용하면 되지만
일반적으론 import방식을 이용한다.
// 패키지 full 경로를 이용
java.util.Date date = new java.util.Date();
어떤 제약 사항이 있는지?
1. 패키지 선언은 반드시 주석과 공백을 제외한 첫 번째 문장이 어야 한다.
2. 하나의 소스파일에 단 한 번만 선언될 수 있다.
3. 소스파일에 포함된 모든 클래스나 인터페이스는 선언된 패키지에 속해야 한다.
4. 클래스명과 구분하기 위해서 소문자로 하는 것을 원칙으로 한다.
5. 숫자로 시작해서는 안되고, _와$를 제외한 특수 문자를 사용해서는 안된다.
6. java로 시작하는 패키지는 자바 표준 API에서만 사용하므로 사용해서는 안된다.
자바에서의 주요 패키지
java.lang 패키지
lang 패키지는 JAVA 프로그래밍에 필요한 가장 기본적인 클래스들이 모여있는 패키지이다. import구문으로 호출해야 사용할 수 있는 다른 패키지들과는 달리 lang패키지는 import구문 없이도 자동으로 프로그램에 포함된다. lang패키지에 포함되는 클래스는 따로 명시하지 않아도 최상위 클래스가 된다.
java.lang패키지에 속한 클래스
String, StringBuffer
Process, Runtime, Thread
Math, StrictMath
Exception Throwable, Error
Package, Class, ClassLoader
Wrapper, System, Stream
java.util 패키지
Java의 java.util 패키지(Package)는 Java 프로그래밍에 유용한 클래스들을 모아둔 것으로 대표적인 클래스로는 날짜와 관련된 Date, Calendar 가 있으며, 자료구조와 관련된 Collection 프레임워크 관련 클래스들이 포함되어 있다.
java.util에 속한 클래스
AbstractCollection,
AbstractList, AbstractSequentialList, LinkedList, ArrayList, Vector, Stack,
AbstractSet, HashSet, LinkedHashSet, TreeSet,
AbstractMap, HashMap, LinkedHashMap, TreeMap,
Arrays, BitSet, Calendar, GregorianCalendar,
Collection, Date, Dictionary, Hashtable, Properties,
EventObject, Locale, Observable, Random, Scanner, StringTokenizer
java.io 패키지
Java의 java.io 패키지(Package)는 java.nio 패키지와 함께 파일이나 통신 등 디지털 정보의 입출력을 처리하는 클래스가 정의된 패키지이다. 대표적인 바이트 스트림(Byte Stream) 처리 인터페이스는 InputStream과 OutputStream이 있으며, 문자열(Character Stream) 방식 입출력 처리를 위한 클래스로는 Reader와 Writer 추상 클래스가 정의되어 있다.
java.time패키지
Java에서 날짜, 시간, 날짜와 시간에 대한 파싱, time-zone 등을 정의한 패키지이다.
더 자세한 사항은 (백기선 님 강의 中 더 자바 8에 대한 요약된) TIL 저장소에서 확인 가능하다.
2) import 키워드
위의 예에서 보았듯이 다른 패키지의 클래스를 사용하려면 클래스가 포함된 패키지 이름을 import 시켜주어야 한다고 했다. import문은 일반적으로 package문 다로 다음에 위치한다.
어떻게 선언하는지?
import 패키지명.클래스명;
또는
import 패키지명.*;
" import 패키지명.*; "의 의미는 해당 패키지에 있는 모든 클래스를 사용한다는 의미이다.
필요하지 않는 클래스까지 import 시키면 성능상 문제가 되지 않을까 생각이 들지만 실행 시 성능상의 차이는 전혀 없다.
지금까지 우리가 System이나 String 같은 java.lang패키지의 클래스들은 패키지명 없이 사용할 수 있었던 이유는 모든 소스파일에 묵시적으로 import java.lang.*; 이 선언되어 있기 때문이다.
⌨ 이클립스에는 패키지 자동 import라는 기능이 있다.
단축키 : ctrl + shift + o
⌨ 인텔리제이에서는 사용하지 않는 import를 지우는 기능이 있다.
- mac : ctrl + option + O
- windows/linux : ctrl + alt + O
- 자동 import 설정 : action 검색 -> optimize imports on -> Auto import -> OFF를 ON으로
static import
static import문을 사용하면 static 멤버를 호출할 때 클래스 이름을 생략할 수 있다.
만일 static import 문을 선언하였다며 첫 번째 코드를 두 번째 코드와 같이 간략히 할 수 있다.
1. Double pi = Math.PI;
=> import static java.lang.Math.*; 추가 후
2. Double pi = PI;
3) classpath
개념
클래스 패스란 말 그대로 클래스를 찾기 위한 경로이다. 컴파일러나 JVM의 클래스 로더는 runtime시 .class파일을 찾는 기준이 되는 경로를 말한다.
클래스 파일이 포함된 경로는 윈도 기준 ;로 구분 짓는다.
예를들어 .;C:\windows\system32;c:\Program Files\Java\Jdk1.8.0\bin; 이라면
1. .(점)
2. C:\windows\system32
3. :\Program Files\Java\Jdk1.8.0\bin
이 세 경로들은 명령 프롬프트상에서 프로그램을 실행시킬 때 실행파일을 찾는 경로 정보로 활용이 된다.
myclass 디렉터리 안에서 정상 실행되던 것이 mysubclass에 AAA.class와 BBB.class를 옮기면 실행이 되지 않으며 클래스가 보이지 않는다는 오류가 발생한다.
이유는 기본적으로 아무런 설정을 하지 않으면 java.exe가 실행된 디렉터리에서만 가상 머신에 올려진 클래스를 찾기 때문이다. 그렇다면 어떠한 설정을 해야 할까
"java.exe를 실행시킨 현재 디렉터리의 서브 디렉터리인 mysubclass 디렉터리에서 해당 클래스를 찾아보세요"라는 설정을 해주면 된다.
즉, set classpath=.;C:\myclass\mysubclass; 대강 이런 식으로 지정해주면 된다.
클래스 로더에는 3가지 종류가 있다.( 더자바 코드를 조작하는 다양한 방법 中)
클래스 로더는 계층 구조로 이뤄져 있으며 차례대로 실행된다.
- 부트 스트랩 클래스 로더 - JAVA_HOME\lib에 있는 코어 자바 API를 제공한다. 최상위 우선순위를 가진 클래스 로더
- 플랫폼 클래스로더 - JAVA_HOME\lib\ext 폴더 또는 java.ext.dirs 시스템 변수에 해당하는 위치에 있는 클래스를 읽는다.
- 애플리케이션 클래스로더 - 애플리케이션 클래스 패스(애플리케이션 실행할 때 주는 -classpath 옵션 또는 java.class.path 환경 변수의 값에 해당하는 위치)에서 클래스를 읽는다.
클래스 패스를 지정할 수 있는 두 가지 방법이 있는데 한 개는 classpath 환경 변수를 사용하는 법, -classpath 플래그를 사용하는 법이 있다.
4) classpath 환경 변수
환경 변수 PATH는 windows가 명령 프롬프트상에서 실행파일을 찾는 경로의 정보가 된다.
명령 프롬프트상에서 디렉터리 경로에 상관없이 프로그램의 이름을 입력하여, 해당 프로그램을 실행하기 원한다면 환경변수 PATH에 실행파일의 위치를 등록해야 한다. (windows만 해당)
윈도우즈에서는 제어판 - 시스템 - 고급 시스템 설정 - 환경변수에서 추가 가능하다.
예시)
JAVA_HOME의 변수 값이 어떻게 저장되어 있는지 확인한다.
시스템 변수의 - path로 들어가 편집을 누른다.
아래와 같이 %JAVA_HOME%가 포함되어 있는지 확인한다.
새로만들기를 통해 클래스패스를 추가한다
아래와 같이 나타나면 성공이다.
5) -classpath 옵션
-classpath 또는 -cp 옵션을 통해 일시적으로 클래스 패스를 지정해 줄 수도 있다.
예를 들어 C:\myPath 폴더를 기준으로 A.class를 실행할 때
java -classpath "C:\myPath" A 를 실행하면 된다.
6) 접근 지시자(access modifier, =접근 제어자)
접근 지시자는 멤버 또는 클래스에 사용되어 해당하는 멤버 또는 클래스를 외부에 접근하지 못하도록 제한하는 역할을 한다. 접근 지시자가 default임을 알리기 위해 실제로 default를 붙이지는 않는다.
클래스, 멤버 변수, 메서드, 생성자에 접근 지시자가 지정되어 있지 않다면, 접근 지시자가 default임을 뜻한다.
- private : 같은 클래스 내에서만 접근이 가능하다.
- default : 같은 패키지 내에서만 접근 가능하다.
- protected : 같은 패키지 내에서, 그리고 다른 패키지의 자식 클래스에서 접근 가능하다.
- public : 접근 제한 없이 전역에서 사용 가능하다.
대상이 무엇인지에 따라서 접근 지시자를 사용하는데 제한이 있다.
- 클래스 : public, (default)
- 메서드 / 멤버변수 : public, protected, (default), private
- 지역변수 : 사용할 수 없음
접근 지시자를 사용하는 이유 - (자바의 정석)
특정 데이터를 외부에 노출되지 않아야 되는 경우들이 있다. (가령 비밀번호라던지 개인 신상정보 등이 있다)
이러한 데이터가 유효한 값을 유지하도록 외부로부터 접근을 제한하는 것이 필요하다.
이러한 것을 데이터 감추기(data hiding)이라 하며 객체지향 개념의 캡슐화(encapsulation)에 해당한다.
또 다른 이유는 클래스에서만 사용되는, 내부 작업을 위해 임시로 사용되는 멤버 변수나 부분 작업을 처리하기 위한 메서드 등의 멤버들을 클래스 내부에 감추기 위해서 이다.
정리
1. 외부로부터 데이터를 보호하기 위해
2. 외부에는 불필요한, 내부적으로만 사용되는, 부분을 감추기 위해
접근지시자의 조합 - (자바의 정석)
클래스 : public, (default), final, abstract
메서드 : 모든 접근 지시자, final, abstract, static
멤버변수 : 모든 접근 지시자, final, static
지역변수 : final
주의사항
1. 메서드에 static과 abstract를 함께 사용할 수 없다.
- static메서드는 몸통이 있는 메서드에만 사용할 수 있다.
2. 클래스에 abstract와 final을 동시에 사용할 수 없다.
- abstract와 final은 서로 반대의 기능
3. abstract메서드의 접근 제어자가 private일 수 없다.
- private이면 자식클래스 접근할 수없다.
4. 메서드에 private와 final을 같이 사용할 필요는 없다.
- 접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문이다.
Reference
자바의 정석(남궁성)
'Java' 카테고리의 다른 글
8주자 과제: 인터페이스 (0) | 2021.01.09 |
---|---|
7주차 과제: 패키지 (피드백, feedback) (0) | 2021.01.02 |
6주차 과제: 상속 (feedback, 피드백) (0) | 2020.12.27 |
6주차 과제: 상속 (0) | 2020.12.26 |
4주차 과제: 제어문(feedback, 피드백) (0) | 2020.12.22 |