[JAVA] Static
-멤버변수, 멤버메서드에 적응할 수 있는 키워드
-정적 변수(클래스의 변수), 정적 메소드(클래스의 메소드)를 선언할 때 사용
자바프로그램의 구동 과정
1. JVM에 의해서 실행할 모든 클래스 중 static 메소드, static 멤버필드를 수집해서 메모리에 로딩되고 프로그램의 시작(main 메소드의 실행) 전에 메모리 적재됨
2. 메모리에 로딩된 static 메소드 중 main 이름을 검색
3. main 메소드가 검색되었다면 JVM해당 main 메소드를 호출하여 프로그램 시작
class StaticA{
int num; // instance member variable(동적 멤버변수)
static int number=100; // static member variable(정적 멤버변수)
}
public class Class {
public static void main(String[] args) {
// 동적멤버변수(인스턴스멤버변수)는 객체가 반드시 생성되어야 그 변수가 생성되고 사용할 수가 있음
System.out.println("Static class의 정적멤버변수 값: "+StaticA.number);
// -> Static class의 정적(static) 멤버변수 값: 100
StaticA a1=new StaticA();
a1.num=100;
System.out.println("a1 객체의 동적 멤버변수 값: "+a1.num);
// -> a1 객체의 동적 멤버변수 값: 100
// 그러나 static 변수는 main 메서드 실행 전에 객체 생성 전
// 미리 생성되어 있는 변수, 객체와는 독립적이면서 클래스에는 종속적으로 사용하도록 생성됨.
// 객체를 생성하지 않고도 사용할 수 있는 클래스의 멤버변수임.
// 동적변수는 객체생성마다 그 객체안에 생성되서 객체의 갯수만큼 생성되지만
// 정적변수는 프로그램 전체를 통틀어 한개 만들어짐.
// 그 값도 일관성 있게 끝까지 유지됨
StaticA a2=new StaticA();
a2.num=200;
System.out.println("a2 객체의 동적 멤버변수 값: "+a2.num);
// -> a2 객체의 동적 멤버변수 값: 200
System.out.println("Static class의 정적멤버변수 값: " +StaticA.number);
// -> Static class의 정적(static) 멤버변수 값: 100
StaticA a3=new StaticA();
a3.num=300;
System.out.println("a3 객체의 동적 멤버변수 값: "+a3.num);
// -> a3 객체의 동적 멤버변수 값: 300
System.out.println("Static class의 정적멤버변수 값: " +StaticA.number);
// -> Static class의 정적(static) 멤버변수 값: 100
// 동적 변수와 마찬가지로 private으로 보호 되지 않았다면 임의 접근이 가능
StaticA.number=10;
System.out.println("a 객체의 정적 멤버변수 값: " +StaticA.number);
// -> a 객체의 정적 멤버변수 값: 10
// private로 보호된 static변수는 static 메서드를 사용하여 값을 저장하거나 얻어냄.
// static이 아닌 멤버 메서들에서는 접근이 불가능.
}
}
static method
-static 멤버변수와 같이 프로그램 구동 전에 메모리에 로딩되어 객체 생성없이 사용할 수 있는 메서드
-static 멤버변수와 같이 사용 시에 메서드 이름 앞에 클래스의 이름을 붙여서 사용함
java.lang
-import 하지 않아도 원래 import 되어져서 사용할 수 있게 존재하는 패키지(클래스)
-간단한 공용기능을 제공하기 위한 Math 클래스(java, lang 패키지 안에 있는 클래스)
-Math 클래스 안에 public static int abs(int n){}와 같은 양식의 sqrt, random 메서드가 있음( abs: 절대값 계산 메서드, sqrt: 제곱근 계산 메서드, random: 난수 발생 메서드)
-Math 클래스의 random 메서드는 Random 클래스의 nextInt() 메서드와
양식은 다르지만 역할은 같은 메서드
-Math 클래스의 random 메서드는 static 메서드이므로 Math.random(); 와 같이 사용함
-Random 클래스의 nextInt() 메서드는 동적 멤버메서드이므로 import도 별도로 해야하고 new 명령으로 객체 생성 후 호출 객체를 앞에 두고 사용함
Instance method
class StaticD{
// private로 지정된 static멤버는 클래스의 내부에서만 사용이 가능한 멤버
private static int count;
// static 멤버는 static 메서드와 인스턴스 메서드 둘에서 모두 접근 가능
// private로 지정된 static멤버를 이용하고자 한다면 public으로 지정된 멤버메서드(static, 인스턴스)로 이용함
public static void setCount(int count) { StaticD.count=count;}
public static int getCount() {return count;}
// 다만 인스턴스 메서드는 객체 생성후 이용 가능
// 스태틱 변수와 매개변수가 이름이 같을 때 아래와 같이 StaticD.count 클래스 이름을 써서 구분함
public void setCount1(int count ) { StaticD.count=count;}
public int getCount1() {return StaticD.count;}
}
public class Static {
public static void main(String[] args) {
// private로 지정된 static 멤버는 클래스의 외부에서 접근이 차단됨
// StaticD.count=100; ->error
// public 접근지정자를 사용하는 static 메소드로 private으로 지정된 static 멤버의 값을 이용할 수 있음
System.out.printf("StaticD.count=%d\n",StaticD.getCount());
StaticD.setCount(15);
System.out.printf("StaticD.count=%d\n",StaticD.getCount());
// 인스턴스 메서드는 객체 생성 후 사용 가능
StaticD d1=new StaticD();
System.out.printf("StaticD.count=%d\n",d1.getCount1());
d1.setCount(15);
System.out.printf("StaticD.count=%d\n",d1.getCount1());
}
}
초기화 블록
class StaticE{
private int number;
private static int num=1;
// 일반 초기화 블럭: 객체 생성시 실행(생성자와 성격이 비슷) 단순 값으로 초기화하는 경우
// 대입연산자를 통해서 처리할 수 있지만 실행문이 포함된 초기화를 진행하는 경우
// 아래와 같이 초기화 과정을 정의할 수 있음
{
number=100;
System.out.println("인스턴스 변수 초기화 용 초기화 블럭1");
}
// static 초기화 블럭: static 멤버를 초기화하기 위한 영역
// 단순 값으로 초기화하는 경우 대입연산자를 통해서 처리할 수 있지만 실행문이 포함된 초기화를 진행하는 경우
// 아래와 같이 초기화 과정을 정의할 수 있음
static {
System.out.println("StaticF의 static 블럭 실행");
num=55;
}
// static 블럭은 객체 생성 이전에 실행됨
// 일반 초기화블럭에서는 스태틱 멤버에 접근이 자유롭게 가능함
static int cnt=-;
int serialNo;
{
++cnt;
serialNo=cnt;
System.out.println("인스턴스 멤버접근은 제한됨");
}
// 스태틱 초기화 블럭에서 인스턴스 멤버접근은 제한됨
}
public class Class {
public static void main(String[] args) {
StaticE f=new StaticE();
}
}