티스토리 뷰

Java

[Java] static 키워드

nohriter 2022. 9. 1. 21:34

Java의 static 키워드는 필드, 메서드, 클래스에 적용할 수 있습니다.

static 키워드를 사용하여 선언하였을 때 각각 어떤 차이점이 있는지 알아보겠습니다.

 

 

 

 

1. static field(변수, 상수)


클래스 안에서 변수를 선언하면 멤버 변수로 선언이 되며,  멤버변수에 접근하려면 car1.name 처럼 객체를 통해서 접근해야 한다.

Car car1 = new Car();
System.out.println(car1.name)

만약 static 키워드를 사용하여 변수를 선언하면 멤버 변수와 다른 특성을 갖게되는데,

아래와 같이 객체 car1을 통해서 접근할 수 있지만, 클래스 Car를 통해서도 접근할 수 있다.

System.out.println(Car.sNumberOfCars);

Car car1 = new Car();
System.out.println(car1.sNumberOfCars);

 

클래스를 통해서 접근을 하게 되면, 객체를 만들지 않고 외부에서 접근할 수 있다.

static으로 선언된 변수는 프로그램이 실행될 때 생성 및 초기화되기 때문에 객체를 생성하지 않아도 이미 변수는 생성된 상태이다.

 

아래에 Car 클래스에는 3개의 static field가 존재한다.

public class Car {

    public final static String MANUFACTURE_NAME = "BMW";
    public final static String CAR_NAME = "BMW 320D";

    public static int sNumberOfCars = 0;

    public Car() {
        sNumberOfCars++;
    }
}

위의 코드에서 static으로 선언된 변수는 Car 객체를 생성하지 않아도 접근이 가능하다.

 

  • MANUFACTURE_NAME와 CAR_NAME는 final static으로 선언했기 때문에 값 변경이 안되는 상수(Constant)이다.
  • sNumberOfCars는 static으로 선언했기 때문에 언제나 값을 변경할 수 있는 변수(Variable)가 된다.
💡 보통 static 상수를 쉽게 구분하기 위해 대문자와 _ 만을 사용하여 이름을 짓는다.

 

클래스 이름을 통해서 접근

static field는 아래와 같이 객체를 생성하지 않고 클래스 이름을 통해서 접근할 수 있다. 위 코드에서 sNumberOfCars 는 Car 객체를 생성할 때 1이 증가되도록 구현되었기 때문에 모든 객체들이 하나의 변수를 공유하기 때문에 3이 출력된다.

Car car1 = new Car();
Car car2 = new Car();
Car car3 = new Car();

System.out.println(Car.CAR_NAME);
System.out.println(Car.MANUFACTURE_NAME);
System.out.println("Number of cars : " + Car.sNumberOfCars);

출력:

BMW 320D
BMW
Number of cars : 3

 

객체를 통해서 접근

static field도 아래와 같이 객체를 통해서 접근할 수도 있다. 하지만 static field는 Class를 통해서 접근하는 방법을 권장한다. 그 이유는 멤버 변수를 접근하고 있는지, static 변수를 접근하고 있는지 구별이 어렵기 때문이다.

Car car1 = new Car();
Car car2 = new Car();
Car car3 = new Car();

System.out.println(car1.CAR_NAME);
System.out.println(car1.MANUFACTURE_NAME);
System.out.println("Number of cars : " + car1.sNumberOfCars);

 

static field를 사용하는 이유

static field는 대부분 상수(인스턴스들마다 공통된 값)를 선언할 때 많이 사용되며, 이렇게 상수를 선언하면 다른 클래스에서도 Car.MANUFACTURE_NAME을 통해 상수에 접근할 수 있다.

public class Car {
  public final static String MANUFACTURE_NAME = "BMW";
  public final static String CAR_NAME = "BMW 320D";
}

 

중요핵심

1. static field는 프로그램이 실행될 때 생성 및 초기화되기 때문에 객체를 생성하지 않아도 접근이 가능하다.

2. static으로 상수를 선언할 때는 CAR_NAME 처럼 관습적으로 대문자와 _를 이용하여 이름을 짓는다.

3. static field는 클래스와 객체를 통해서 모두 접근이 가능하지만, 클래스를 통해서 접근해야 한다.(구분이 어렵기 때문)

4. static으로 상수가 아닌, 변수를 선언하는 일은 많지 않다. static 변수를 많이 선언하면 객체지향과 멀어지고 스파게티 코드가 될 수 있기 때문이다.

 

 

 

2. static 메서드


static 메서드도 static field와 비슷하게 메서드를 선언할 때 static을 사용하면 객체를 생성하지 않아도 그 메서드를 호출할 수 있다.

public class Car {
    public final static String MANUFACTURE_NAME = "BMW";
    public final static String CAR_NAME = "BMW 320D";

    public int year = 2018;

    public Car() {
    }

    public static void printCarName() {
        System.out.println("{ Brand : " + MANUFACTURE_NAME + ", Name : " + CAR_NAME + " }");
    }
}

static filed와 마찬가지로 printCarName()도 클래스와 객체를 통해서 모두 호출이 가능하다. 하지만 객체의 메서드를 호출하는 것인지 static 메서드를 호출하는 것인지 구분이 안되기 때문에 클래스를 통해서만 호출되어야 한다.

Car.printCarName();

Car car1 = new Car();
car1.printCarName();
🚨 static 메서드 주의할 점

static 메서드는 객체를 생성하지 않아도 호출할 수 있다. 이것은 메서드가 객체와 분리되어 있다는 의미다. 그래서 메소드 내부에서 super, this와 같은 키워드를 사용할 수 없고 클래스의 멤버 변수에 접근할 수도 없다. 내부에 선언된 변수 외에 static field, static 메소드만 접근할 수 있다.

 

중요핵심

1. static 메서드는 객체 생성 없이 호출할 수 있다. 그렇기 때문에 멤버 변수에 접근할 수 없고, static field 또는 메서드만 접근 가능하다.

2. static 메서드는 객체 및 클래스를 통해서 호출할 수 있지만, 멤버 메서드와 구분하기 어렵기 때문에 클래스를 통해서만 호출해야 한다.

3. static 메서드는 객체 생성 없이 호출 가능하기 때문에 Utils 클래스들을 만드는데 많이 사용된다.

4. static 메서드는 클래스이름.메서드명 과 같이 작성하기 때문에, 클래스 속성과 연관된 메서드를 묶어주는 효과가 있다.

 

 

 

3. static 클래스


자바는 외부 클래스에 static 키워드를 붙일 수 없지만, inner 클래스에는 static 키워드를 붙일 수 있다.
따라서 static 클래스를 이해하기 위해서는 inner 클래스를 알아야 한다. (이글에서는 내부 클래스에 대한 설명은 하지 않겠다)

 

위에서 static 메서드는 객체를 생성하지 않아도 호출할 수 있기 때문에 메서드와 객체가 분리되어 있다고 했다.

static 클래스도 분리라는 의미에서 비슷한 특성이 있다. static 키워드를 이용하여 class를 선언하면, 상위 클래스와 분리를 해 준다.

아래에 예시로 Car 클래스 하위에 Wheel 클래스를 선언하였다. 이런 구조로 선언된 Wheel 클래스를 Inner class라고 부르며, Inner class의 특징 중 하나는 상위 클래스와 연결되어 있는 것이다. 그래서 Wheel 클래스는 상위 클래스인 Car 클래스의 멤버 변수에 접근이 가능하다.

public class Car {
    public int year = 2018;

    public Car() {
    }

    public class Wheel {
        public Wheel() {
            year = 10;
        }
    }
}

 

만약 아래와 같이 static으로 Wheel클래스를 선언하면 Car 클래스와 분리가 되고, 분리되었다는 것은 Wheel 클래스에서 Car 클래스의 멤버변수에 접근할 수 없다는 의미이다. 이렇게 static으로 선언된 하위 클래스를 Static nested class라고 한다.

public class Car {
    public int year = 2018;

    public Car() {
    }

    public static class Wheel {
        public Wheel() {
            // year = 10; // compile error!
        }
    }
}

 

Static nested class는 상위 클래스가 생성되지 않아도, 외부에서 직접 객체를 생성할 수 있다.

아래와 같이 하위 클래스를 외부에서 직접 객체를 생성할 수 있고, 이것이 Inner class와의 가장 큰 차이점이라고 할 수 있다.

Car.Wheel wheel = new Car.Wheel();

static class를 사용하면 특정 클래스와 연관된 클래스들을 하위에 선언하여 관련있는 클래스들을 모아둘 수 있다.

 

 

 

출처

 

Java - Static 키워드 이해하기

Java의 static keyword는 field, method, class에 적용할 수 있습니다. static 키워드의 공통점은 객체와의 분리입니다. 객체를 생성하지 않고 접근할 수 있습니다. 또한, 어떤 클래스 아래에 static 변수, 메소

codechacha.com

 

'Java' 카테고리의 다른 글

[Java] 8.인터페이스  (0) 2022.09.07
[Java] 7.패키지  (1) 2022.08.31
[Java] 오버라이딩(Overriding)  (1) 2022.08.24
[Java] 자바는 왜 다중상속을 지원하지 않을까?  (0) 2022.08.24
[Java] 6.상속  (0) 2022.08.24
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/07   »
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 31
글 보관함