코린이의 소소한 공부노트

임포트와 스태틱 임포트 본문

Java

임포트와 스태틱 임포트

무지맘 2022. 4. 14. 13:20

import문은 이미 여러 번 만나봐서 무엇을 말하는지는 짐작할 것이다.

import java.util.Date;

클래스 위에 import문을 선언해두면, 해당 클래스 또는 해당 패키지 안에 있는 클래스를 불러다 쓸 수 있는 것으로 알고 있을 것이다. 나 또한 그랬다. 그러나 import문은 사용자를 위한 것이 아닌, 컴파일러를 위한 것이었다! 띠로리..

 

import문은

1. 컴파일러에게 클래스가 속한 패키지가 무엇인지 알려준다.

  - 클래스 이름이 중복되는 것이 많기 때문에, 어느 패키지에 속해있는지 아는 게 중요하다.

  - 해당 클래스를 불러와서 쓰려고 할 때, 어디로 갈지 그 길을 알려준다.

2. 사용자가 패키지 이름을 생략할 수 있게 만들어준다.

  - 원래 클래스를 사용할 때 패키지 이름을 꼭 써줘야 한다.

  - import문을 이용하면 패키지 이름을 생략할 수 있다.

// 1) import문 없이 Date 클래스 사용하기
java.util.Date d1 = new java.util.Date();

// 2) import문 사용 후 Date 클래스 사용하기
import java.util.Date;
// 메인 내부
Date d2 = new Date();

1)에서는 패키지(java.util)까지 다 써야 했지만, 2)에서는 클래스 이름만 쓰면 된다. 만약 클래스 이름만 쓰고 import문을 작성하지 않았다면 컴파일 에러가 발생하지만, 문제없다.

  - 에러가 난 부분에 커서를 갖다 대면 이런 식의 해결책을 제시해주는데, 여기서 내가 사용하고자 했던 Date 클래스가 있는 패키지 import문을 선택하거나,

  - ctrl+shift+o를 눌러서 원하는 import문을 고르면 된다.

 

그런데 말입니다, 우리 지금까지 생각해보면 패키지 선언 없이 썼던 클래스들이 꽤 있지 말입니다?

  - String: 문자열 클래스

  - Object: 모든 클래스의 조상 클래스(=시조새). 상속받는 클래스가 없다면 자동으로 이 클래스를 상속받게 되어있음

  - System: print문 쓸 때 가장 많이 봤음

  - Thread: 실행에 관련된 클래스. 하나의 프로세스라고 생각하면 편함

이 클래스들은 모두 java.lang 패키지에 있는데, 이 패키지는 기본 패키지라서 import하지 않아도 사용 가능하다.

 

[import문 선언 방법]

1. 선언 방식은 2가지가 있다.

// #1
import 패키지명.클래스명;
// #2
import 패키지명.*; // 패키지 내의 모든 클래스

  - import문은 앞서 말했듯 컴파일러를 위한 문장이다. 컴파일 시에 처리되는 문장이므로 프로그램 성능에 영향을 미치지 않는다. 이게 무슨 뜻이냐면...

// 1) 같은 패키지 내에 있는 클래스를 따로 import
import java.util.Calendar;
import java.util.Date;

// 2) *을 이용한 import
import java.util.*;

// 2)가 더 느리다고 생각하겠지만 차이가 없다

  - *을 이용한 import문을 스타 임포트문(star import)라고도 부르는데, 이것의 의미를 정확히 알아야 한다. 예시로 확인해보자.

// 1)
import java.util.*;
import java.text.*;

// 2)
import java.*;

1)의 경우에는 java.util 패키지의 모든 클래스 + java.text 패키지의 모든 클래스를 import한 것이고, 2)의 경우에는 java 패키지의 모든 클래스를 import한 것이다. 여기서 주의할 것은, 하위 패키지까지 다 불러오는 것이 아니라 클래스만 불러온다는 것이다. 아래 그림을 보면 쉽게 이해할 수 있다. 1)의 경우가 노란색, 2)의 경우가 초록색이다.

2. import문은 패키지문과 클래스 선언 사이에 위치한다.

package testpackage;
import java.util.Date;
public class TestClass { }

3. 이름이 같은 클래스가 속한 두 패키지를 import 할 때는 클래스 앞에 패키지명을 붙여야 한다.

import java.sql.*; // 여기에도 Date 클래스가 있고
import java.util.*; // 여기에도 있다.

// 메인내부에서
java.util.Date d1 = new java.util.Date(); // 헷갈리지 않게 하기 위해 꼭 붙여주기

 

import문은 패키지 이름을 생략하게 해 준다. 바꿔 말하면, 클래스 이름만 쓰게 해 준다. 그런데 코드가 길어지면 이마저도 귀찮을 때가 생긴다. 이럴 때 우리에게 도움을 주는 것이 스태틱 임포트(static import)다.

 

static import문은 어떤 클래스의 static 멤버(변수, 메서드)를 사용할 때 클래스 이름을 생략할 수 있게 해 준다. 때에 따라서 모든 멤버에 적용할 수도, 특정 변수나 메서드에만 적용할 수도 있다.

1. 한 클래스의 모든 static 멤버에 대해 static import를 하려면 *을 이용하면 된다.

// 1) 일반 import
import java.lang.Integer.*; // java.lang 패키지는 사실 import 안해도 사용 가능
// 메인 내부
System.out.println(Integer.toBinaryString(4)); // "100"

// 2) static import
import static java.lang.Integer.*; // Integer 클래스의 모든 static 멤버
// 메인 내부
System.out.println(toBinaryString(4)); // "100"

2. 어떤 클래스의 static 메서드를 import 할 때는 괄호를 생략한다.

// 1) 일반 import
import java.lang.Math;
// 메인 내부
System.out.println(Math.random()); // 0.44342001015729104

// 2) static import
import static java.lang.Math.random;
// 메인 내부
System.out.println(random()); // 0.013888202693727258

3. 어떤 클래스의 static 변수만 import할 수도 있다.

// 1) import문 쓰기 전
System.out.println("Hi!"); // "Hi!"

// 2) static import
import static java.lang.System.out; // out은 static 변수
// 메인 내부
out.println("Hi!"); // "Hi!"

위에서 본 것들을 합하면 아래와 같이 쓸 수 있다.

import static java.lang.System.out;
import static java.lang.Math.*;

// 메인 내부
out.println(random()); // 0.9934083702839541
out.println(PI); // 3.141592653589793

개인적으로, static import는 정말 필요하지 않다면 안 쓰는 것도 나쁘지 않겠다는 생각을 했다.

'Java' 카테고리의 다른 글

접근 제어자를 이용한 캡슐화  (0) 2022.04.18
제어자  (0) 2022.04.16
패키지와 클래스 경로  (0) 2022.04.13
생성자 super() vs 참조변수 super  (0) 2022.03.23
메서드 오버라이딩 (+오버로딩과의 차이점)  (0) 2022.03.22