필드와 메소드는 선언 방법에 따라 인스턴스 멤버와 정적 멤버로 분류할 수있다.
인스턴스 멤버로 선언되면 객체 생성 후 사용할 수 있고, 정적 멤버로 선언되면 객체 생성 없이도 사용할 수 있다.
인스턴스 멤버 : 객체에 소속된 멤버(필드, 메소드)를 의미. 따라서 객체가 있어야만 사용할 수 있는 멤버
* 인스턴스 필드를 이용하지 않는 메소드는 정적 메소드로 선언하는 것이 좋다.
예를들어 Calculator의 plus() 메소드들은(다양한 매개변수를 처리하기 위해 오버로드 되있음) 외부에서 주어진 매개값들을 가지고 처리하므로 정적 메소드로 선언하는 것이 좋다.
그러나 인스턴스 필드인 color를 변경하는 setColor() 메소드는 인스턴스 메소드로 선언해야 한다.
public class Calculator {
String color; // 인스턴스 멤버
void setColor(String color) { this.color = color; }
static int plus(int x, int y) { return x + y; }
static int minus(int x, int y) { return x - y; }
}
정적 멤버 : 메소드 영역의 클래스에 고정적으로 위치하는 멤버.
클래스 로더를 이용해서 클래스를 메소드 영역에 저장하고 사용하는 것에 대비 된다!
=> 따라서 정적 멤버는 객체를 생성할 필요 없이 클래스를 통해 바로 사용이 가능하다. (Ex. 클래스명.정적필드명)
정적 블록
정적 필드는 필드 선언과 동시에 초기값을 주는 것이 일반적인데 복잡한 초기화 작업이 필요하다면 정적 블록을 이용해야한다.
public class Television { static String company = "MyCompany"; static String model = "LCD"; static String info; static { info = company + "-" + model; } }
- 정적 블록은 클래스가 메모리로 로딩될 때 자동으로 실행된다.
- 메소드는 코드의 덩어리이므로 객체마다 저장한다면 중복 저장으로 인해 메모리 효율이 떨어진다.
따라서 메소드 코드는 객체가 저장되어있는 힙 영역이 아닌 메소드 영역에 두되 공유해서 사용하고, 이때 객체 없이는 사용하지 못하도록 제한을 걸어둔 것이다.
: 값을 변경하는 것을 막고 읽기만 허용할때 사용.
final 필드에 초기값을 줄 수 있는 두 가지 방법
- 필드 선언시에 초기값 대입
- 생성자에서 초기값 대입
public class Korean { // 인스턴스 final 필드 선언 (1번 방식) final String nation = "대한민국"; final String ssn; <br/> // 인스턴스 필드 선언 String name; <br> // 생성자 선언 (2번 방식) public Korean(String ssn, String name) { this.ssn = ssn; this.name = name; } }
상수는 다음과 같이 선언한다
static final 타입 상수 (= 초기값);
: 애플리케이션 전체에서 단 한 개의 객체만 생성해서 사용하고 싶을때 사용.
생성자를 호출할 수 없기에 외부에서 마음대로 객체를 생성하는 것이 불가능해지는 대신 싱글턴 패턴이 제공하는 정적 메소드를 통해 간접적으로 객체를 얻을 수 있다.
public class 클래스 {
private static 클래스 singleton = new 클래스();
private 클래스() {}
public static 클래스 getInstance() {
return singleton;
}
}
클래스 변수1 = 클래스.getInstance();
클래스 변수2 = 클래스.getInstance();
위 코드에서 변수1, 변수2가 참조하는 객체는 동일한 객체가 된다.
참조:
이것이 자바다 교육 현장에서 가장 많이 쓰이는 JAVA 프로그래밍의 기본서 [ 개정판 ] - 신용권, 임경균 저 | 한빛미디어
https://blog.wanzargen.me/16