일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Class
- geometry
- dynamic programming
- string
- 자바
- sorting
- Counting
- array
- 파이썬
- java
- Binary Tree
- Data Structure
- greedy
- Method
- simulation
- hash table
- database
- bit manipulation
- 코테
- SQL
- implement
- 코딩테스트
- Stack
- two pointers
- Math
- Number Theory
- Matrix
- 구현
- Tree
- Binary Search
- Today
- Total
코린이의 소소한 공부노트
임포트와 스태틱 임포트 본문
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 |