ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 7주차 과제: 패키지
    Programming/Java live study 2020. 12. 30. 15:27
     

    whiteship/live-study

    온라인 스터디. Contribute to whiteship/live-study development by creating an account on GitHub.

    github.com

    목표

    자바의 패키지에 대해 학습하세요.

     

    학습할 것

     

    • package 키워드
    • import 키워드
    • 클래스패스
    • CLASSPATH 환경변수
    • -classpath 옵션
    • 접근지시자

    1. package 키워드

    1.1 package의 개념

     Java에서 package란 서로 관련 있는 클래스나 인터페이스의 컴파일된 클래스 파일들을 한 곳에 묶어 놓은 것을 말한다. 각각의 package는 디렉토리와 유사하다. 하나의 package는 클래스 파일들을 모아둔 디렉토리이다. 

     

    Java package 구조

     클래스를 지칭하기 위해서는 package명을 포함하는 경로명을 사용한다. 

     

    List<Integer> list = new java.util.ArrayList<>();

     

     java.util은 package를 의미하고, ArrayList 클래스는 java/util 디렉토리에 존재한다. package와 클래스 명 사이에는 . 을 찍어서 분리한다. 이렇게 표현한 것을 FQCN(Fully Qualified Class Name)라 부른다. FQCN은 클래스가 속한 패키지명을 모두 포함한 이름이다.

     

     package만 다르다면 클래스 명은 중복되어도 상관없다. 클래스 명은 package단위에서 유일하면 된다. 

     

    java.util.List<Integer> list = new java.util.ArrayList<>();
    java.awt.List awtList = new java.awt.List();

     

     서로 다른 package에 있는 클래스 파일이기 때문에 가능하다. 

    1.2 package 명명규칙

     - 회사 이름이나 혹은 도메인(웹 사이트 주소)등으로 구분하여 사용한다.

     - 웹 사이트 주소의 경우 주소를 반대로 기재한 형태로 패키지 이름을 부여한다. 만약 hyeonic.tistory.com 이라면, com.tistory.hyeonic으로 부여한다.

     - 명칭은 소문자를 사용한다. 대문자 사용이 가능하지만 사용하지 않을 것을 권고한다.

     - 특수문자는 '_', '$'만 사용이 가능하다.

     - Java의 예약어는 사용할 수 없다.

     

    1.3 Built-in package

     Java에는 package 종류를 크게 두 개로 나눌 수 잇다. 사용자가 정의한 package와 Java API에 포함되는 클래스를 포함하는 Built-in package이다.

     

    package 종류

     Built-in package에는 language support 클래스가 들어있는 java.lang, 유틸리티를 구현한 클래스가 들어있는 java.util 등이 들어 있다.  Built-in package에서 자주 쓰이는 몇 가지를 찾아보았다. 

     

    • java.lang : language suport 클래스들을 포함하고 있다.
      • 자동으로 import 되기 때문에 java.lang에 정의된 클래스들은 바로 사용할 수 있다.
      • String s = new String(); // java.lang.String()과 같다.
      • System.out.print(); // java.lang.System.out.print()와 같다.
    • java.io : 입출력 기능을 지원하는 클래스들을 포함하고 있다.
    • java.util : 자료 구조 구현을 위한 유틸리티 클래스를 포함하고 있다.
    • java.awt : GUI 컴포넌트 구현을 위한 클래스를 포함하고 있다.

     그 밖에도, java.net, java.math, java.time 등이 있다.

     

    1.4 사용자 정의 package

     사용자가 직접 정의한 package를 의미한다. 

     

    package me.hyeonic;
    
    public class Person {
    
        private String name;
        
        public String getName() {
            return this.name;
        }
        
        public void setName(String name) {
            this.name = name;
        }
    }

     

    package me.hyeonic;
    
    import me.hyeonic.Person;
    
    public class Main {
    	public static void main(String[] args) {
            Person person = new Person();
            person.set("hyeonic");
        }
    }

     

     me.hyeonic의 경우 개발자가 직접 생성한 디렉토리이기 때문에 사용자가 직접 정의한 package이다.


    2. import 키워드

    2.1 import 문

     애플리케이션의 클래스가 다른 package에 있는 클래스를 사용할 때는 package명을 포함하는 경로명을 사용해야 한다. 컴파일러가 클래스 파일의 위치를 정확하게 찾을 수 있도록 명시해야 한다.

     

     하지만 이렇게 클래스를 사용할 때마다 경로명을 명시하면 코드가 길어지고 어지러워 진다. 이런 경우 import 문을 사용하여 전체 경로명을 컴파일러에게 알려준다.

     

    import java.util.ArrayList;
    import java.util.List;

     

     import 문은 다른 package의 클래스를 사용할 때 그 클래스의 경로명을 선언하여 컴파일러에게 알려주는 역할을 한다. 그렇기 때문에 import 문은 클래스 선언 전에 나와야 한다.

     

    public class Main {
    
        public static void main(String[] args) {
        
            java.util.List<Integer> list = new java.util.ArrayList<>();
        }
    }

     

    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
    
        public static void main(String[] args) {
        
            List<Integer> list = new ArrayList<>();
        }
    }

     

     

     사용 전 후를 비교해 보면, 사용 후의 코드가 깔끔하고 보기 좋은 것을 알 수 있다.

     

     만약 클래스에서 java.util package의 모든 클래스를 사용하기 위해서는 와일드 카드를 사용해서 명시할 수 있다.

     

     

    import java.util.*;

     

    import java.util.*;
    
    public class Main {
    
        public static void main(String[] args) {
        
            List<Integer> list = new ArrayList<>();
        }
    }

     

     해당 import 문에 사용된 클래스는 java.util에 들어있는 모든 클래스 파일이 사용가능하다. 

     

     단, 같은 package에 있는 클래스라면, import 하지 않아도 사용할 수 있다!

    2.2 static import

     static 메소드나 필드를 더욱 쉽게 사용하기 위해 JDK 1.5부터 지원한다. static 메소드로 자주 사용하는 Math 클래스를 예시로 사용하였다.

     

    public class MathTest {
    
        public static void main(String[] args) {
    
            int a = 10;
            int b = 20;
    
            int max = Math.max(a, b);
            double area = a * a * Math.PI;
    
            System.out.println(max);
            System.out.println(area);
        }
    }

     

     간단한 Math 클래스를 사용하는 예제이다. Math의 max 메소드와 PI 필드는 모두 static 이기 때문에 클래스를 생성하지 않고 사용할 수 있다. 추가적으로 static import를 사용하면 앞에 명시된 클래스 명을 제외하고 사용할 수 있다.

     

    import static java.lang.Math.*;
    
    public class MathTest {
    
        public static void main(String[] args) {
    
            int a = 10;
            int b = 20;
    
            int max = max(a, b);
            double area = a * a * PI;
    
            System.out.println(max);
            System.out.println(area);
        }
    }

     

     깔끔하게 max와 PI만 명시한 것을 알 수 있다. 그 밖에도 static import를 사용하면 JUnit의 Assertions.assertThat() -> assertThat() 으로 사용이 가능하다.


     

    3. 클래스패스

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Main {
    
        public static void main(String[] args) throws IOException {
            
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String s = reader.readLine();
    
            System.out.println(s);
        }
    }

     

     간단하게 입력받은 문장을 console에 출력해주는 소스 파일이다. 해당 소스 파일을 컴파일하여 실행할 때, java.io안에 있는 클래스들은 두 가지 방법을 사용하여 실제 디스크의 위치를 찾는다.

     

     1. 클래스 경로의 환경 변수, CLASSPATH

     2. java -classpath 옵션

     

     먼저 CLASSPATH 환경 변수부터 알아보자.

     

    3.1 클래스패스 환경 변수

     JVM은 클래스에서 사용하는 라이브러리 클래스의 위치를 찾기위해 CLASSPATH 환경 변수에 지정된 경로를 확인한다.  윈도우 10을 기준으로 환경 변수 설정 방법을 알아보자!

     

     우선 자신이 사용하기 위한 JDK를 다운받는다. 필자는 Zulu OpenJDK 11 버전을 사용하고 있다.

     

    Java Download | Java 8, Java 11, Java 13 - Linux, Windows & macOS

    Download Java Builds of OpenJDK 8, 11, 13 & 15. Azul Zulu Builds of OpenJDK runs on Linux, Windows, macOS & Solaris on X86, Arm, SPARC & PPC

    www.azul.com

     해당 파일을 다운 받아 적절한 폴더에 압축을 푼다. 예를 들면, C:\JAVA에 풀었다고 가정하자. 

     

    C:\JAVA\zulu11.43.55-ca-jdk11.0.9.1-win_x64

     

     이제 JDK를 설치한 디렉토리를 가리키는 JAVA_HOME 환경변수를 만들어야 한다. eclipse, InIntelliJ와 같은 idea는 기본적으로 JAVA_HOME 환경변수를 사용한다.

     

    내 PC를 우클릭하여 속성을 클릭한다.

     

    제어판의 고급 시스템 설정에 들어간다.
    하단에 환경 변수를 클릭한다.

     

    사용자 변수와 시스템 변수에 새로 만들기를 클릭한다.
    JAVA_HOME 환경 변수를 만든다.
    JDK 디렉토리 아래에 bin 디렉토리에 Java 실행파일들이 들어 있다.

     

     마지막으로 cmd 창을 열어 java -version으로 Java 버전을 확인한다!

     

     이렇게 설정하면 JVM은 운영체제의 환경변수를 참고하여 애플리케이션을 실행한다. 하지만 이렇게 운영체제 자체에 CLASSPATH 환경변수 설정을 넣는 것은 권장하지 않는다. 운영체제를 변경하거나 JDK의 버전을 바뀌면 CLASSPATH를 참조하던 애플리케이션이 해당 클래스를 찾지 못할 수도 있다. 이러한 방법으로도 설정이 가능하다는 것만 알아두자.

    3.2 -classpath 옵션

     shell에서 Java를 실행할 때 다음과 같이 -classpath 옵션을 주어 직접 클래스 파일의 위치를 지정할 수 있다.

     

    java -classpath "클래스 파일의 위치" *.java

     

     classpath 옵션은 -cp로 축약해서 사용 가능하고, javac, java 모두 사용이 가능하다.

    3.3 IDE의 자동 classpath 설정

     운영체제에서 환경변수를 가져다 사용하지 않고 IDE나 Maven과 같은 빌드 도구를 통하여 classpath를 설정할 수 있다.


    4. 접근지시자

    접근 지시자 기능
    public 클래스 내부와 외부에서 모두 호출 가능하다.
    protected 클래스 내부에서 메소드 호출이 가능하다. 외부에서 호출하기 위해서는 해당 클래스를 상속받은 서브 클래스만 가능하다.
    private 클래스 내부에서만 메소드 호출이 가능하다.
    defualt 접근 지정자가 생략된 형태이고, 동일한 패키지 내의 모든 클래스에서 호출이 가능하다.

     

    부모 클래스 멤버에 접근하는 클래스
    부모 클래스 멤버의 접근 지시자
    defualt private protected public
    같은 패키지의 클래스 O X O O
    다른 패키지의 클래스 X X X O
    같은 패키지의 자식 클래스 O X O O
    다른 패키지의 자식 클래스 X X O O

     

     Singleton Pattern은 접근지시자의 특성을 잘 활용한 예시이다.  https://hyeonic.tistory.com/23

     

     

    References.

     

    황기태, 김효수 지음 명품 JAVA Programing

     

     

    [Java] 자바의 패키지와 클래스패스

    자바의 패키지와 클래스패스를 알아보자 :raising_hand:

    ahnyezi.github.io

     

     

     

    'Programming > Java live study' 카테고리의 다른 글

    9주차 과제: 예외 처리  (0) 2021.01.13
    8주차 과제: 인터페이스  (0) 2021.01.05
    6주차 과제: 상속  (0) 2020.12.24
    5주차 과제: 클래스  (0) 2020.12.24
    4주차 과제: 제어문  (0) 2020.12.24

    댓글

Designed by Tistory.