static

hyyyynjn·2021년 5월 9일
0

자바 스터디

목록 보기
11/15
post-thumbnail
  • static에 대해서 설명하기

class Foo {
    public static String classVar = "I Class Var";
    public String instanceVar = "I instance Var";

    public static void classMethod() {
        System.out.println(classVar); // ok : static 변수에 접근 가능
        // System.out.println(instanceVar); // error : instance 변수에 접근 불가능
    }

    public void instanceMethod() {
        System.out.println(classVar); // ok
        System.out.println(instanceVar); // ok
    }
}

public class StaticExample {

    public static void main(String[] args) {

        System.out.println(Foo.classVar); // ok
        // System.out.println(Foo.instanceVar); // error

        Foo.classMethod(); // ok
        // Foo.instanceMethod(); // error

        Foo f1 = new Foo();
        Foo f2 = new Foo();
//
        System.out.println(f1.classVar); // I class var
        System.out.println(f1.instanceVar); // I instance var
//
        f1.classVar = "changed by f1";
        System.out.println(Foo.classVar); // changed by f1
        System.out.println(f2.classVar);  // changed by f1
//
        f1.instanceVar = "changed by f1";
        System.out.println(f1.instanceVar); // changed by f1
        System.out.println(f2.instanceVar); // I instance var

    }
}

static 메모리

  • ✋우리가 만든 Class 👉 Static 영역에 생성된다
    • Static 영역은 모든 객체가 공유하는 메모리이고,
    • GC의 관리 영역 밖에 존재하기때문에 프로그램 종료시까지 메모리가 할당된 채로 존재한다
      • JDK 8부터 힙 영역이 기존에 New / Survive / Old / Perm / Native 에서 New / Survive / Old / Metaspace 로 변경 되었다.
      • ✋Java7 까지의 Permanent에 Static Object가 존재했지만
        👉 Java8 에서의 Metaspace과 Heap 분리되면서
        Static Object상수화된 String Obejct
        Heap 영역으로 이동하게 되었다
    • static 변수, 메소드를 남용하면 시스템 성능에 영향을 준다
  • ✋new 연산으로 만든 Instance 👉 Heap 영역에 생성된다
    • Heap 영역은 GC를 통해 수시로 관리 받는다.

static 변수

  • 메모리에 고정적으로 할당되어, 프로그램이 종료될 때 해제되는 변수이다
    • 해당 클래스 객체를 생성하지 않고도 static 자원에 접근할 수 있다
      static 변수, static 메소드
      👉 객체가 생성되기 이전에 이미 static 영역에 할당되므로, 객체 생성 없이 바로 접근할 수 있다.
      👉 멤버변수 중에서 모든 인스턴스에 공통적으로 사용해야 하는 것이 있다면 static을 붙인다.

✍예시

public class Person {
    private String name = "Hjoon";
	    
	public void printName() {
	    System.out.println(this.name);
	}
}
// 👉
public class Person {
    public static final String name = "Hjoon";
         
    public static void printName() {
        System.out.println(this.name);
    }
}
  • person 객체를 여러개 생성하면 "Hjoon"이라는 작은 값을 가지는 메모리가 중복되어 생성된다
    • 👉 static을 사용하여 여러 객체가 하나의 메모리를 참조하도록한다 (메모리 효율적)
    • 👉 final 키워드를 사용한다 (변하지 않을 값이므로)
    • 👉 public으로 선언한다 (변수가 아니라 상수의 값을 가질 경우에만)
    • public static final String name = "Hjoon"
  • static 변수를 사용하는 메소드는 static으로 선언되어야 한다
    • public static void printName()

✍활용

public final class AppConstants {
 
    public static final String APP_NAME = "MyApp";
    public static final String PREF_NAME = "MyPref";        
 
}
  • 상수의 변수명은 대문자와 _를 조합하여 이름짓는다
  • 상속을 방지하기 위해 final class로 선언을 한다.

static 메소드

  • 객체 생성 없이 호출 가능한 메소드이다 👉 객체에서 호출 가능하지만, 지양한다
  • 일반적으로 Utility 관련 함수들은 여러번 사용되므로 static 메소드로 구현한다
    • java.util.Math라는 Util Class
public class StaticExample {
    private String name1 = "Hjoon";
    private static String name2 = "Hjoon";
 
    public static void printMax(int x, int y) {
        System.out.println(Math.max(x, y));
    }
         
    public static void printName(){
       // System.out.println(name1); 불가능한 호출
       System.out.println(name2);
    }
}
  • static 메소드 public static void printMax(int x, int y)
    • static 메소드로 선언된 Math 클래스의 max함수를 초기화 없이 사용한다
  • static 메소드 public static void printName()
    • 👉 name2 : 객체가 생성되기 이전에 메모리가 Static 영역에 할당된다
      • 접근 가능
    • 👉 name1 : new 연산으로 객체가 생성된 후 메모리가 Heap 영역에 할당된다
      • static 으로 선언되지 않은 변수는 아직 메모리가 할당되지 않으므로 접근 불가능

✍활용

public final class CommonUtils {
 
    public static String getCurrentDate() {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        return dateFormat.format(date);
    }
     
    public static boolean isEmailValid(String email) {
        return Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }
     
}
  • 상속을 방지하기 위해 final class로 선언을 한다.

정리

  1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통적으로 사용해야하는 것에 static을 붙인다.
  2. static이 붙은 멤버변수는 인스턴스를 생성하지 않아도 사용할 수 있다.
  3. static이 붙은 메서드(함수)에서는 인스턴스 변수를 사용할 수 없다.
  4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
  5. 작성한 메서드 중에서 인스턴스 변수를 사용하지 않는 메서드에 대해서 static을 붙일 것을 고려한다

0개의 댓글