Binary World

JAVA CLASS : 접근 제한자(final 변수, static 변수) 본문

개발자의 길/JAVA

JAVA CLASS : 접근 제한자(final 변수, static 변수)

모쿠 2016. 12. 30. 16:44
<final 변수, static 변수>


* Java Runtime(실행 환경, VM(virtual machine)이 관리하는 메모리:

 - Stack(스택): 지역 변수들이 저장되는 메모리 영역

 - Heap(힙): 인스턴스(참조 자료형)가 저장되는 메모리 영역

 - Method(메소드): static으로 선언한 변수, 메소드의 실행 코드들이 저장되는 메모리 영역


1. final 변수


- 초기화된 값을 바꿀 수 없음.

- 예) final int y = 10; // 변경 불가

- final: 최종적인, 변경할 수 없는

- final + 멤버 변수, 지역 변수: 상수(한번 초기화된 값을 변경할 수 없는 변수)

- final + 메소드: override할 수 없는 메소드

- final + 클래스: 상속을 허용하지 않는 클래스


2. static 변수


1) 멤버 변수 또는 메소드를 선언(정의)할 때 사용

 - 인스턴스 생성 이전에 프로그램이 처음 시작될 때 static 메모리 영역에 자동으로 생성


2) 클래스 변수(static 변수): static으로서 선언한 멤버 변수

 - 인스턴스를 생성하지 않아도 사용 가능

 - static 변수는 생성되는 모든 인스턴스들이 공유하게 됨!(중요)

 - 클래스이름.변수이름 형식으로 사용


3) 인스턴스 변수: static이 붙지 않은 멤버 변수

 - 인스턴스를 생성한 후에만 사용할 수 있는 변수

 - 참조변수.변수이름 형식으로 사용


4) 클래스 메소드(static 메소드): static으로 선언한 메소드

 - 인스턴스를 생성하지 않아도 사용 가능한 메소드

 - 클래스이름.메소드() 형식으로 사용


5) 인스턴스 메소드: Static이 붙지 않은 메소드

 - 인스턴스를 생성한 후에만 사용할 수 있는 메소드

 - 참조변수.메소드() 형식으로 사용


<Java Practice>


1. final 변수 예제


* AccessMain09.java


package edu.java.access09;


public class AccessMain09 {


public static final int MENU_INSERT = 1;

public static final int MENU_DELETE = 2;

public static int test = 100;

public static void main(String[] args) {

// final: 더이상 바꿀 수 없는

int x =10;

final int y = 10;

x = 123;

// 일반적인 지역 변수는 초기화 이후에도 언제든지 값을 변경 가능

// y = 100;

// final 지역 변수는 처음 초기화된 값을 변경할 수 없음!

test = 200;

// final이 아닌 멤버 변수는 언제든지 초기값을 변경 가능


} // end main()


} // end class AccessMain09

 


2. Static 변수의 사용 예제


* TestStatic.java(static 변수 및 메소드)


package edu.java.access10;


// Java Runtime(실행 환경, VM(virtual machine)이 관리하는 메모리:

// 1. Stack(스택): 지역 변수들이 저장되는 메모리 영역

// 2. Heap(힙): 인스턴스(참조 자료형)가 저장되는 메모리 영역

// 3. Method(메소드): static으로 선언한 변수, 메소드의 실행 코드들이 저장되는 메모리 영역

//

// static: 멤버 변수 또는 메소드를 선언(정의)할 때 사용

//    - 인스턴스 생성 이전에 프로그램이 처음 시작될 때 static 메모리 영역에 자동으로 생성

// 클래스 변수(static 변수): static으로서 선언한 멤버 변수

//    - 인스턴스를 생성하지 않아도 사용 가능

//    - static 변수는 생성되는 모든 인스턴스들이 공유하게 됨!(중요)

//    - 클래스이름.변수이름 형식으로 사용

// 인스턴스 변수: static이 붙지 않은 멤버 변수

//    - 인스턴스를 생성한 후에만 사용할 수 있는 변수

//  - 참조변수.변수이름 형식으로 사용

// 클래스 메소드(static 메소드): static으로 선언한 메소드

//    - 인스턴스를 생성하지 않아도 사용 가능한 메소드

//    - 클래스이름.메소드() 형식으로 사용

// 인스턴스 메소드: Static이 붙지 않은 메소드

//    - 인스턴스를 생성한 후에만 사용할 수 있는 메소드

//    - 참조변수.메소드() 형식으로 사용


public class TestStatic {

int num1; // 인스턴스 멤버 변수

static int num2; // 클래스 멤버 변수

// 인스턴스 메소드

public void display1(){

System.out.println("num1 = " + num1);

System.out.println("num2 = " + num2);

}

// 클래스(static) 메소드

public static void display2(){

//System.out.println("num1 = " + num1); - error

// static 메소드는 인스턴스 생성 없이 사용 가능함

// 그런데, 인스턴스 멤버 변수는 인스턴스가 생성된 후에만 사용 가능

// 그래서, static 메소드에서 static이 아닌 멤버 변수 접근은 불가

System.out.println("num2 = " + num2);

}


} // end class TestStatic



* AccessMain10(변수 출력 및 변경해주는 메인 메소드)


package edu.java.access10;


public class AccessMain10 {

public static void test1(){

System.out.println("테스트1");

}

public void test2(){

System.out.println("테스트2");

} // static으로 선언하지 않았기 때문에 main()에서 인스턴스를 생성해야 사용 가능


public static void main(String[] args) {

// static(클래스) 멤버 변수 - 인스턴스 생성 없이 사용 가능

System.out.println(TestStatic.num2);

TestStatic.num2 = 123;

// static(클래스) 메소드 - 인스턴스 생성 없이 사용 가능

TestStatic.display2();

// TestStatic 클래스의 인스턴스를 생성

TestStatic test = new TestStatic();

System.out.println(test.num1);

test.num1 = 100;

test.display1();

TestStatic test2 = new TestStatic();

test2.display1();

TestStatic.num2 = 456;

test.display1();

test2.display1();

test2.num2 = 789;

test.display1();

test2.display2();

test1();

AccessMain10.test1();

AccessMain10 t2 = new AccessMain10(); // 인스턴스 생성해야 가능

t2.test2();

} // end main()


} // end class AccessMain10



3. Private static을 이용한 싱글톤 디자인 패턴(singleton design pattern)


* AccessMain11(메인 출력 클래스)


package edu.java.access11;


public class AccessMain11 {


public static void main(String[] args) {

// Captain 클래스의 인스턴스 생성

Captain c1 = Captain.getInstance();

c1.setName("손현민");

System.out.println(c1);

System.out.println(c1.getName());

System.out.println();

Captain c2 = Captain.getInstance();

System.out.println(c2);

System.out.println(c2.getName());

System.out.println();

c2.setName("진혁");

System.out.println(c1);

System.out.println(c2);

System.out.println(c1.getName());

System.out.println(c2.getName());


} // end main()


} // end class AccessMain11

 



* Captain.java (인스턴스 메소드 정의 클래스)


package edu.java.access11;


// 싱클톤 디자인 패턴(singleton design pattern)

// 클래스의 인스턴스를 오직 하나만 생성할 수 있도록 작성하는 설계 기법

// 1. 클래스 자신 타입의 private static 변수를 선언

// 2. 생성자는 private으로 선언

// 3. public static 메소드를 제공해서 인스턴스를 생성할 수 있도록

// 처음 들어간 인스턴스는 변경이 불가능(주소값이 같음)


public class Captain {

private String name;


// 1. private static Captain 변수를 선언

private static Captain instance = null;


// private 생성자

private Captain() {

}


// 3. public static 메소드를 정의

public static Captain getInstance() {

if (instance == null) {

instance = new Captain();

}

return instance;

}


public String getName() {

return name;

}


public void setName(String name) {

this.name = name;

}


} // end class Captain  



* 출력화면


edu.java.access11.Captain@15db9742

손현민


edu.java.access11.Captain@15db9742

손현민


edu.java.access11.Captain@15db9742

edu.java.access11.Captain@15db9742

진혁

진혁


- comment : c1과 c2의 주소값이 같다 


Comments