이전에 멤버 변수를 설명하면서 클래스 변수를 설명하면서 static 단어를 잠깐 언급한 적이 있다.
인스턴스 멤버와 정적 멤버를 다시 한번 더 정리하면서 static에 대해 알아보도록 하자.
인스턴스 멤버와 this
인스턴스 멤버란 객체를 생성한 후 사용할 수 있는 필드와 메소드라고 말할 수 있다.
객체 내부에서 인스턴스 멤버에 접근하기 위해 this를 사용해야 한다.
저번에 생성자를 설명하면서 말했던 것처럼 this는 객체 자신을 가르킨다.
생성자와 메소드의 매개 변수 이름이 필드와 동일한 경우 인스턴스 멤버인 필드를 명시하고 할 때 사용한다.
Car(String company){
this.company = company;
}
즉, 위의 코드는 매개 변수 company의 값을 필드 company에 저장한다고 설명할 수 있다.
정적 멤버와 static
정적은 고정된 것을 뜻하는데
정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다.
정적 필드와 정적 메소드를 선언할 때 맨 앞에 static을 사용하면 된다.
객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언하고,
객체마다 가지고 있을 필요가 없는 공용 데이터라면 정적 필드로 선언하는 것이 좋다.
예를 들어 원의 둘레나 넓이를 구할 때 필요한 파이(𝝅)처럼 4
객체마다 가지고 있을 필요없는 변하지 않는 공용 데이터를 말할 수 있다.
그리고 메소드는 인스턴스 필드를 포함하고 있다면 인스턴스 메소드로 선언하고,
인스턴스 필드를 포함하고 있지 않다면 정적 메소드로 선언하면 된다.
예를 들어 계산기의 덧셈, 뺄셈, 나눗셈, 곱셈의 기능은 외부에서 주어진 매개값을 가지고 수행하므로
정적 메소드로 선언하는 것이 좋다.
public class StaticEx {
int num1 = 0; // 인스턴스 멤버
static int num2 = 0; // 클래스 멤버
}
public class StaticExApp {
public static void main(String[] args) {
StaticEx se1 = new StaticEx();
StaticEx se2 = new StaticEx();
se1.num1++;
se1.num2++;
System.out.println("se1.num1 : " + se1.num1);
System.out.println("se1.num2 : " + se1.num2);
System.out.println("se2.num1 : " + se2.num1);
System.out.println("se2.num2 : " + se2.num2);
}
}
// 결과
se1.num1 : 1
se1.num2 : 1
se2.num1 : 0
se2.num2 : 1
위의 코드 결과를 보다싶이 인스턴스 멤버와 다르게 클래스 멤버인 static은 값이 공유되는 것을 볼 수 있다.
객체를 생성하지 않고 사용할 수 있다고 말했었는데 이는 클래스 이름과 함께 도트(.) 연산자로 접근할 수 있다.
public class Calculator {
static int add(int x, int y) {
return x+y;
}
}
public class CalculatorApp {
public static void main(String[] args) {
// 객체를 생성하지 않고 클래스 이름으로 접근
int areaResult = Calculator.add(1,2);
System.out.println(areaResult);
}
}
정적 메소드 선언 시 주의할 점
1) 정적 메소드를 선언할 때에는 이들 내부에 인스턴스 필드나 인스턴스 필드를 사용할 수 없다.
2) 객체 자신의 참조인 this 키워드를 사용할 수 없다.
만약 정적 메소드에서 인스턴스 멤버를 사용하고 싶다면 다음과 같이 객체를 먼저 생성하고 참조 변수로 접근해야 한다.
main() 메소드에서도 마찬가지이니 잘 기억하도록 하자.
public class staticEx {
String name;
static void example() {
// name = "코린이"; // 에러 발생
staticEx ex = new staticEx();
ex.name = "코린이";
}
}
※ import static
import static으로 불러오는 클래스 안의 모든 static 메소드를 현재 클래스의 메소드인 것처럼 불러오게한다.
import static을 사용하지 않은 코드(1)
public class StaticTest {
public static void main(String[] args) {
int x = Math.max(1,5);
System.out.println(x);
}
}
import static을 사용한 코드(1)
import static java.lang.Math.max;
public class StaticTest {
public static void main(String[] args) {
int x = max(1,5);
System.out.println(x);
}
}
위의 코드처럼 import static을 사용한다면 Math.을 생략할 수 있다.
import static을 사용하지 않은 코드(2)
package ex;
public class Static {
public static void print(String msg) {
System.out.println(msg);
}
}
package ex;
import ex.Static.*;
public class StaticTest {
public static void main(String[] args) {
Static.print("import static으로 출력하지 않음");
}
}
import 뒤에 static을 사용하지 않으면 Static.print()로 사용해야하는 것을 볼 수 있다.
import static을 사용한 코드(2)
package ex;
import static ex.Static.*;
public class StaticTest {
public static void main(String[] args) {
print("import static으로 출력함");
}
}
import static을 사용한다면 Static.을 생략하고 print()로 바로 사용할 수 있는 것을 볼 수 있다.
'국비 지원 > JAVA' 카테고리의 다른 글
[JAVA] 접근 제한자 (0) | 2023.05.13 |
---|---|
[JAVA] 오버로딩과 오버라이딩 (0) | 2023.05.13 |
[JAVA] 날짜 클래스(SimpleDateFormat와 Calendar) (0) | 2023.05.07 |
[JAVA] 오버로딩과 this() (0) | 2023.05.06 |
[JAVA] 필드, 생성자 - 기본 생성자, 메소드 (0) | 2023.05.06 |