클래스 변수,메소드 와 인스턴스 변수,메소드의 차이?
static 선언을 붙여서 선언하는 클래스 변수는 왜 필요할까 ?
인스턴스 변수 << 인스턴스가 생성되었을때, 안에 존재하는 변수.
class Circle{
int radius=0; //요놈이 인스턴스 변수
final double PI =3.14; //요놈도 인스턴스 변수, final은 상수이므로 바뀌지 않는 값.
Circle(int r){
radius=r;
}
}
class Main{
public static void main(String[] args){
Circle c=new Circle(4); // 요놈이 인스턴스
}
}
각 원의 반지름은 모두 다르기때문에 원의 반지름은 인스턴스 변수로 사용해야한다.
하지만 원주율 3.14는 모든 원이 같은 값을 가지고있다. 따라서 이는 모든 인스턴스가 각각 지녀야할 값이 아니다.
그렇다면 Circle class에있는 PI는 모든 원이 공유하는 값이므로 앞에 static을 붙혀주면 된다.
class Circle{
int radius=0; //요놈이 인스턴스 변수
static final double PI =3.14; //이젠 클래스 변수
Circle(int r){
radius=r;
}
}
그 변수를 이제 클래스 변수라고 부른다.
클래스 변수의 특성으로는
1. 클래스변수는 인스턴스 내에 존재하는 변수가 아니라, 어떠한 인스턴스에 속하지않는 메모리 공간에 딱 하나 존재하는 변수다.
그 클래스에서 접근할 수 있는 어떤 전역변수같은 느낌이라고 보면된다.
2. 인스턴스 생성 이전에 메모리 공간에 존재한다.
class Circle{
int radius=0;
static final double PI =3.14; //클래스변수의 초기화 방법
Circle(int r){
radius=r;
//PI=3.14 클래스변수는 생성자로 초기화하지않는다 >> 인스턴스 생성 전에 초기화가 되기때문
}
}
class Main{
public static void main(String[] args){
System.out.println("PI값 : " + Circle.PI); //인스턴스 생성 없이 바로 접근했다
}
}
보면 Circle의 인스턴스 생성 없이 바로 PI에 접근했다. 이말은
클래스 변수는 인스턴스 생성 이전에 메모리공간에 존재한다는 말이고, 해당 클래스 정보가 가상머신에 읽히는 순간 메모리공간에 할당되고 초기화된다.
클래스 메소드도 마찬가지다
>>인스턴스 생성 이전부터 접근이 가능하다
>>어느 인스턴스에도 속하지 않는다
class Printer(){
private int num=0;
static void ShowInt(int r){ //클래스 메소드
System.out.println(r);
}
void setNum(int n){
num=n;
}
void getNum(){
ShowInt(num);
}
}
class MainClass{
public static void main(String[] args){
Printer.ShowInt(10); //클래스 이름을 이용해 바로 클래스 메소드에 접근했다
Printer myPrinter=new Printer();//인스턴스 생성
myPrinter.showInt(20); //인스턴스로부터 클래스 메소드에 접근했다.
}
}
Printer.ShowInt(10)이 정상적으로 작동되는것으로보아
클래스메소드는 어떤 인스턴스에도 속하지 않는다는것을 알 수 있다.
그렇다면 클래스 변수는 그렇다치고 클래스 메소드는 언제써야할까 ?
요놈이 중요하다.
class Calculator{
double addDouble(double a, double b){
return a+b;
}
}
class MainClass{
public static void main(String[] args){
Calculator myCal=new Calculator(); //인스턴스를 생성했다
System.out.println("1+2 : " + myCal.addDouble(1,2));
}
}
이 코드를 보면 Calculator 클래스 내에는 인스턴스 변수가 없고, 참조하거나 수정하지도 않는다. 모두 외부에 기능을 제공하는 메소드이다. 따라서 이 메소드는 인스턴스에 속할 이유가 없다.
class Calculator{
static double addDouble(double a, double b){
return a+b;
}
}
class MainClass{
public static void main(String[] args){
//인스턴스 생성 생략
System.out.println("1+2 : " + Calculator.addDouble(1,2));
}
}
static 변수는 초기화하는 방법에 static 초기화 블록이라는 방법이 있다.
만약 프로그램 실행 날짜를 static 변수에 담고싶다면
class DateExecution{
static String date;
static{ //static 초기화 블럭
LocalDate nDate = LocalDate.now();
date = nDate.toString();
}
public static void main(String[] args){
System.out.println(date);
}
}