언어/JAVA

[JAVA] Static

hvoon 2022. 9. 7. 17:52

-멤버변수, 멤버메서드에 적응할 수 있는 키워드

-정적 변수(클래스의 변수), 정적 메소드(클래스의 메소드)를 선언할 때 사용

자바프로그램의 구동 과정

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();
	}
}