천천히 빛나는
Java 기초 : 클래스 멤버 - static의 사용 본문
전에 다룬 내용이지만 복습 중 자세히 작성하는 것이 좋을 것 같다고 판단되어 static에 대해 다루기로 하였다.
package javatutorials.numberstring;
import java.util.Scanner; // 입력관련
import java.io.*; // File 관련
class Calculator {
static double PI = 3.14; // 클래스 변수
static int base = 0;
int left, right; // 인스턴스 변수
public void setOprands(int left, int right){
this.left = left;
this.right = right;
}
public void sum(){
System.out.println(this.left + this.right + base);
}
public void avg(){
System.out.println((this.left + this.right)/2);
}
}
public class Number {
public static void main(String[] args) {
Calculator c1 = new Calculator(); // 객체
c1.setOprands(10, 20);
c1.sum();
c1.avg();
Calculator c2 = new Calculator(); // 객체
c2.setOprands(20, 30);
c2.sum();
c2.avg();
Calculator.base=10; // c1.base = 10;
c2.sum();
c2.avg();
}
}
먼저 클래스 변수이다.
static을 변수, 메소드 앞에 붙이면 클래스의 멤버가 된다. 모든 객체가 static 변수를 공유하게 되므로 인스턴스에 따라서 변하지 않는 값으로 사용할 수 있다. 또한 값을 변경하면 모든 인스턴스가 공유하게 된다.
class Calculator {
public static void sum(int left, int right){
System.out.println(left + right );
}
public static void avg(int left, int right){
System.out.println((left + right)/2);
}
}
public class Number {
public static void main(String[] args) {
Calculator.sum(10, 20);
Calculator.avg(10, 20);
}
}
클래스 메소드도 존재하게 된다.
인스턴스 c1, c2, c3과 같이 다른 상태를 가진 객체 (다른 변수값을 가진채로 유지) 가 필요하지 않다면 일회용품처럼 클래스 메소드를 제작할 수 있다.
여기서 중요한 부분이 하나 있다.
1. 인스턴스 메소드는 (static 키워드가 없음) 클래스 멤버 (static 키워드가 있음)에 접근할 수 있다.
2. 클래스 메소드는 (static 키워드가 있음) 인스턴스 멤버 (static 키워드가 없음)에 접근할 수 없다.
2번이 다소 헷갈리는 부분인데, 클래스는 인스턴스보다 먼저 존재하게 된다. 즉 아직 생성하지 않는 메소드에 접근하는 것이라고 생각하면 된다.
인스턴스가 존재한다는 것은 클래스가 이미 존재한다는 것이기 때문에 인스턴스는 클래스 멤버에 접근을 할 수 있게 된다.
package javatutorials.numberstring;
class C1{
static int static_var = 1; // 클래스 변수
int instance_var = 2; // 인스턴스 변수
static void static_static(){ // 클래스메소드가 클래스 변수 호출
System.out.println(static_var);
}
static void static_instance(){ // 클래스메소드가 인스턴스 변수 호출
// 클래스 메소드에서는 인스턴스 변수에 접근 할 수 없다.
System.out.println(instance_var); // 오류!!!!
}
void instance_static(){ // 인스턴스메소드가 클래스변수 접근
// 인스턴스 메소드에서는 클래스 변수에 접근 할 수 있다.
System.out.println(static_var);
}
void instance_instance(){
System.out.println(instance_var);
}
}
public class Number {
public static void main(String[] args) {
C1 c = new C1();
c.static_static(); // 1 출력
c.static_instance(); // 오류, 인스턴스를 이용해서 정적 메소드에 접근은 가능
c.instance_static(); // 1
c.instance_instance(); // 2
C1.static_static(); // 1
C1.static_instance(); // 오류
C1.instance_static(); // 오류
C1.instance_instance(); // 오류
}
}
클래스 변수라는 대신 Static Field 라고도 하고 인스턴스 변수 대신 Non-Static Field라고도 한다.
static을 정적이라고 표현하기도 한다.
public class Number {
static int i = 0;
static void a(){
int i = 0;
}
public static void main(String[] args) {
for (int i = 0; i < 5; i++){
a();
System.out.println(i);
}
}
}
이러한 코드가 있을 때, 함수 a 앞에는 public과 같은 문구가 붙지 않는 이유가 궁금했다. 기본적으로 Java에서 클래스 내에 선언된 메서드의 접근 제어자는 package-private이다. 동일한 패키지 내에서만 해당 메소드에 접근할 수 있는 것이다.
다른 패키지에서도 접근 가능하도록 하려면 public을 붙여주면 된다.
main 함수이 public으로 설정되어있는 이유는 JVM에 의해 호출되어야 하기 때문에 public으로 선언해서 호출할 수 있도록 해야한다.
class C{
int v = 10;
void m(){
int v = 20;
System.out.println(this.v + " " + v);
}
}
클래스 C의 경우 static이나 public을 붙일 수 있을지도 궁금해졌다.
자바에서는 가장 바깥에 있는 클래스한테는 static을 붙일 수 없다. static는 내부에 있는 클래스에서 대해서만 사용할 수 있게 된다. public은 붙여도 되는데 앞서 말한 것처럼 다른 패키지에서도 사용하고자 한다면 붙이면 된다.
static, public과 같은 개념이 이해되길 바라며 글을 마무리 하겠다.
'JAVA > JAVA' 카테고리의 다른 글
Java 기초 : API와 API 문서 보는 법 (0) | 2024.01.16 |
---|---|
Java 기초 : 클래스 패스와 패키지 (0) | 2024.01.15 |
Java 기초 : 정리본 (2) (0) | 2023.08.09 |
Java 기초 : 상속 (0) | 2023.07.31 |
Java 기초 : Enum과 객체 배열 (0) | 2023.07.30 |