천천히 빛나는

Java 기초 : 클래스 멤버 - static의 사용 본문

JAVA/JAVA

Java 기초 : 클래스 멤버 - static의 사용

까만콩 •ᴥ• 2024. 1. 9. 23:50

 

전에 다룬 내용이지만 복습 중 자세히 작성하는 것이 좋을 것 같다고 판단되어 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