static

Mia Lee·2021년 12월 29일
0

JAVA

목록 보기
81/98
package ex_static;

public class Ex1 {

	public static void main(String[] args) {

		/*
		 * 정적(static) 멤버 변수 = 클래스 멤버 변수
		 * 
		 * < 정적(클래스) 멤버 정의 기본 문법 >
		 * static 데이터타입 변수명[= 초기값];
		 *
		 * < 정적(클래스) 멤버 사용 문법 >
		 * 클래스명.변수명;
		 * 
		 */
		
		// StaticEx 클래스의 클래스 변수 a는 클래스가 메모리에 로딩될 때 함께 로딩되므로
		// 인스턴스 생성 전에 메모리에 로딩되며, 인스턴스 생성 없이도 클래스명만으로 
		// 접근 가능한 멤버!
		System.out.println("StaticEx.a = " + StaticEx.a); // 접근가능
//		System.out.println("StaticeEx.b = " + StaticEx.b); // 오류 발생!
		// => 인스턴스 멤버변수 b는 반드시 인스턴스를 통해서만 접근 가능!
		
		// StaticEx 클래스의 인스턴스 생성
		StaticEx se = new StaticEx();
		// => 인스턴스 생성 시 Heap 영역에 인스턴스 멤버도 함께 로딩됨
		
		System.out.println("se.b = " + se.b); // 반드시 인스턴스를 통해 접근
		System.out.println("se.a = " + se.a);
		// => 클래스 멤버변수도 일반 인스턴스 멤버변수처럼 접근 할 수 있으나
		//    가급적 static 접근 방식(클래스명.변수명)으로 접근하도록 하자!
		
		// StaticEx 클래스의 변수 a의 값을 100으로 변경, b의 값을 200으로 변경 후 출력
//		se.a = 100;
		StaticEx.a = 100;
		se.b = 200;
		
		System.out.println("변경 후 se.a = " + se.a);
		System.out.println("변경 후 se.b = " + se.b);
		
		// StaticEx 클래스의 새로운 인스턴스(se2) 생성
		StaticEx se2 = new StaticEx();
		System.out.println("se2.a = " + se2.a); // 변경된 100이 출력
		System.out.println("se2.b = " + se2.b); // 새 인스턴스 값 20 출력
		// => 인스턴스를 새로 생성하더라도 정적 멤버변수는
		//    하나의 메모리 공간을 모든 인스턴스에서 공유하므로
		//    하나의 인스턴스에서 값을 변경하면 모든 인스턴스가 변경된 값을 공유
		
		// 대표적인 static 멤버변수의 예
		// 수학관련 기능을 제공하는 Math 클래스의 멤버변수는 모두 static
		double pi = 3.141592;
		System.out.println("파이 값 : " + pi);
		
		// Math 클래스에 상수 PI가 제공되며 static 멤버변수로 제공
		// => 별도의 인스턴스 생성없이 클래스명만으로 접근 가능
		System.out.println("파이 값 : " + Math.PI);
		
		// 정수를 다루는 Integer 클래스의 멤버변수 static
		System.out.println("INT형 표현범위 최소값 : " + Integer.MIN_VALUE);
		System.out.println("INT형 표현범위 최대값 : " + Integer.MAX_VALUE);
		
	}

}

class StaticEx {
	
	static int a = 10; // 클래스(정적) 멤버변수 선언
	int b = 20; // 인스턴스 멤버변수 선언
	
}





package ex_static;

public class Ex2 {

	public static void main(String[] args) {

		/*
		 * 정적(static) 메서드
		 * 
		 * < 정적 메서드 정의 기본 문법 >
		 * [접근제한자] static 리턴타입 메서드명([매개변수...]) {
		 * 		실행문;
		 * }
		 * 
		 * < 정적 메서드 사용 문법 >
		 * 클래스명.메서드([매개값...]);
		 * 
		 */
		
		// 정적메서드는 인스턴스 생성 전 클래스명을 사용하여 메서드 호출 가능
		StaticEx2.staticMethod(); // 정적 멤버 메서드 호출 가능
//		StaticEx2.normalMethod(); // 인스턴스 멤버 메서드는 호출 불가능!
		
		// 인스턴스 생성 후 메서드 호출
		StaticEx2 se = new StaticEx2();
		se.normalMethod();
		se.staticMethod();
		// 인스턴스 통해 접근해서 메서드 호출도 가능하나 클래스명으로 접근하는 것을 추천!
		
		System.out.println("================================");
		
		// static 멤버도 private 접근제한자 사용 시 외부클래스에서 접근불가
//		System.out.println("StaticEx3.a = " + StaticEx3.a); // 오류 발생!
		
		// 따라서, Getter/Setter를 사용하여 static 멤버에 접근!
//		StaticEx3.getA(); // 오류 발생! 
		// static 메서드로 정의 시 클래스명만으로 접근
		System.out.println("StaticEx3.getA() = " + StaticEx3.getA());
		
		StaticEx3.setA(100); // 정적멤버변수 a 100 저장
		System.out.println("StaticEx3.getA() = " + StaticEx3.getA());
		
		System.out.println("=====================================");
		
		StaticEx3.print();
		
	}

}

// 인스턴스 멤버 생성 후 접근 유무 확인
class StaticEx3 {
	
	// static 멤버변수와 static 메서드 정의 시 주의사항!
	private static int a = 10; // 클래스 로딩 시(인스턴스 생성 전) 함께 로딩 
	private int b = 20; // 인스턴스 생성 시 로딩
	
	// static 멤버변수 a를 리턴하는 Getter 메서드 정의
	public static int getA() {
		return a;
	}
	
	// static 멤버변수 a의 값을 전달받아 초기화하는 Setter 메서드 정의
	public static void setA(int a) {
//		this.a = a; // 오류 발생!
		// => static 메서드 내에서는 레퍼런스 this 사용 불가!
		// => 레퍼런스 this에 저장되는 인스턴스 주소는
		//    인스턴스가 생성되는 시점에서 만들어지므로
		//    static 멤버가 로딩되는 시점에서는 접근 불가능!
		
		// 레퍼런스 this 대신 클래스명을 통해 접근하면 된다!
		StaticEx3.a = a;
		
	}
	
	// 멤버변수 b의 Getter/Setter
	public int getB() {
		return b;
	}
	
	public void SetB(int b) {
		this.b = b;
	}
	
	public static void print() {
		System.out.println("a = " + a);
//		System.out.println("b = " + b); // static 메서드 내에서는 인스턴스 멤버변수 사용 불가
		// => 클래스 로딩 시점에서는 인스턴스 멤버는 생성되기 전이기 때문!(this와 이유가 동일!)
		
		StaticEx3 ex = new StaticEx3();
		System.out.println("ex.b = " + ex.b);
		
	}
	
}

class StaticEx2 {

	public void normalMethod() {
		System.out.println("일반 메서드 normailMehtod()");
	}
	
	public static void staticMethod() {
		System.out.println("정적 메서드 staticMethod()");
	}
	
}
















package ex_static;

public class Ex3 {
	
	/*
	 * static 멤버와 인스턴스 멤버의 생성 시점 차이
	 * - static 멤버는 클래스 내에서 위치와 상관없이 순차적으로 로딩됨
	 * - static 멤버 로딩이 끝난 후 main() 메서드 호출됨
	 * - main() 메서드 내에서 인스턴스 생성 시 인스턴스 멤버가 로딩
	 * - 인스턴스 멤버 로딩이 끝난 후 생성자 호출됨
	 * 
	 */
	
	public int b = callB(); // 인스턴스 변수
	// => 인스턴스 변수 b 생성 시점에 로딩되어 callB() 메서드를 호출(4번)
	public int callB() {
		System.out.println("인스턴스 변수 b 로딩!"); return 0;
	}
	public static int a = callA(); // 정적 변수
	// => 정적 변수 a 로딩 시점에 로딩되어 callA() 메서드를 호출(1번)
	public static int callA() {
		System.out.println("정적 변수 a 로딩!"); return 0;
	}
	public Ex3() { // => 인스턴스 생성 되는 시점에 로딩(5번)
		System.out.println("Ex3 클래스의 인스턴스 생성됨!");
	}
	public static void main(String[] args) {
		// 클래스 로딩 시점에 로딩
		// => 단, 모든 static 멤버의 로딩이 끝난 후 자동으로 main() 메서드 호출
		System.out.println("main() 메서드 호출됨!"); // (3번)
		Ex3 ex = new Ex3(); // 인스턴스 생성
	}
	public static int c = callC(); // 정적 변수
	// => 정적 변수 c 로딩 시점에 로딩되어 callC() 메서드를 호출(2번)
	public static int callC() {
		System.out.println("정적 변수 c 로딩!"); return 0;
	}

}







0개의 댓글