본문 바로가기

Java

정적인 자식 Static

정적멤버 Static

정적 멤버란?

인스턴트 멤버와 달리 클래스에 고정된 필드, 메서드

클래스에 고정되어 메소드 영역에 저장되기 때문에 객체를 만들지 않고 클래스에 도트연산자(.)로 접근해 사용한다,

선언 방법은 별다를꺼 없다 고정된 이라는 뜻의 static을 필드, 메소드 앞에 붙여주면된다. 

예)

static int x;

static void x(){...}

객체 내부에 존재하는게 아니기때문에 모든 객체에 있는것도아니고 사용할때도 new 연산자로 객체를 만들지 않고 

클래스명.정적멤버명();<< 이런방식으로 사용한다.

물론 객체를 만든 뒤 참조변수로 참조 하는것도 가능은 하지만 하지말것.

딱히 할 필요가없다.(내가 모르는걸수도 있다.)

그럼 인스턴스 멤버와 비교해 어떨때 써야하는가. 

필드의 경우 

객체마다 가지고 있어야 하는 데이터 = 인스턴스 

모두가 사용하는 공용 데이터 = 정적멤버

예)

class 계산기

String color;

static double pi=3.14159....

와 같이 계산기(객체)는 저마다 다른 색깔을 가질수도있다. 

하지만 그 안의 PI계산식은?? 달라질수없다 모든 계산기의 파이는 3.14니까


메소드의경우

메소드의 경우는 더 간단하다 필드가 인스턴스일 경우 인스턴스로 

필드가 정적멤버일 경우 정적메소드로 선언한다. 

이유는 정적 멤버의 경우 클래스의 메소드 영역에 저장된다. 인스턴스는 객체내부에 존재한다. 

그렇기때문에 인스턴스는 객체를 생성해야만 사용이가능하다. 객체를 생성하지않고 사용할수있는 정적멤버는 인스턴스멤버를 사용할 수 없다.(사용할수 있는 방법은 있다.)

이러한 이유로 this. 역시 정적멤버에는 사용하지 못한다. this. 는 객체 자신을 가르키는것이기 때문이다.


정적 초기화   

정적멤버의 초기화/초기값의 설정을 위해서는 물론 필드를 생성할때 바로 값을 줄수도 있지만

초기화블록을 만들어서 초기화하는것이 가능하다. 

인스턴스멤버의 경우 생성자로 초기화 하는 것이 가능하지만 위에서 말했다 싶이 정적 멤버는 객체 내부에 존재하는게 아니기 때문에 생성자가 아니라 초기화 블록을 따로 만들어 준다. 

초기화 블록은 클래스가 메소드 영역을 로딩할때 자동으로 실행된다. 

\예)

static{.........}<<이거다.

class 클래스명{

static int x;

static{

x=10;

}

}

이런 방식으로 초기화블록을 사용한다. 예로 든것은 그냥 간단히 초기화 했지만 초기화 블록 내부에는 for,if문등 여러가지 복잡한 연산이 가능하다. 그렇기 때문에 초기화 값으로 복잡한 연산을 진행한 후의 값을 넣어주는것이 가능.

초기화 블록에서 하는일은 정적 필드의 초기화. 정적 메소드의 호출.

초기화 블록은 클래스내부에 여러개있어도 되고 실행될때는 순서대로 실행된다. 

초기화 블록 사용시 주의 사항

초기화 블록은 객체 없이도 사용이 가능하기 때문에 인스턴스 멤버의 사용이 불가능하다. 같은 이유로 this.의 사용도 안된다.

초기화 블록에서 인스턴스멤버를 사용하고 싶다면 먼저 블록안에서 객체를 생성하고 사용하면된다. 

이제 static이 뭔지 알게 되었다. 그럼 생각나는게 없는가 

ㅇㅇ 없다 나도 가르켜줘서 알았다. 

main()메소드는 어떻게 생겼더라>>

public static void main(String[] args){/....}

소오다 메인 메소드는 정적이노 멤바였던 거시다 오오오 스게에;;;;

그래서 같은 클래스밑에 인스턴스 멤버를 생성하고 사용하고 싶어도 메인에서는 객체 생성없이는 사용불가다. 즉

예) public class Car{

int speed;

void run(){////}


public static void main(String[] args){

speed =60;

run();

}

}

이 코드는 사용할 수 없다. 사용하고 싶으면 같은 클래스에 존재하더라도 객체를 생성하고 사용해야한다. 


싱글 (Singletion)

싱글톤은 무엇인가... 바로 나를 말한다. ...하아.....

그게아니라 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야할때가 있다고 한다. (나는 쥐뿔 몰라서 그런경우가 있나 잘 모른다. )

이때 단 하나만 생성된다고 해서 싱글톤이다. 

싱글톤을 만들려면 외부에서 new연산자로 생성자를 호출할수 없도록 막아야한다. (나는 안막아도 불러주는 외부가 없다...... 난 new연산자같은거없어도 호출할수있다.)

생성자를 호출한 만큼 객체가 생성되기 때문이다.   선언 방법은 간단하다 생성자 앞에 private를 붙여준다. \

클래스 자신을 타입으로한 필드를 정적멤버로 선언하고 그앞에 private을 붙인다. 그리고 그 필드에 new 연산자를 사용해 객체를 생성해준다.
예)

public class 클래스{

-필드

private static 클래스 singleton = new 클래스();

-생성자

private 클래스(){...}

-정적메소드

static 클래스 getInstance(){

return singleton;

}

}

이제 이러면 private이 있는 필드와 생성자는 외부에서 호출할수없다. 외부에서 호출하기위해서는 싱클톤이라는 필드를 리턴받는 getInstance(){}를 호출해 사용해야한다. 

그래서 만약 클래스 외부에서 

클래스 x1= 클래스.getInstance();

클래스 x2= 클래스.getInstance();

이런 식으로 클래스를 참조하더라도 객체는 하나뿐이기때문에 x1,2둘다 같은 객체를 참조하게 되는것

final 필드와 상수

파이널은 최종이란뜻이다.  요즘내 인생은 파이널이 아닌가 하는 생각을 한다. 나는... 가...끔...광안리.....수..온...ㅊ..ㅔ...크...르..ㄹ..한다.......

는 개소리고 말 그대로다 파이널 필드는 한번 값을 초기화 하면 값이 바뀔수 없는 필드이다. 

파이널 필드에 초기값을 주는 방법은 두 가지 있다. 다른 필드랑 똑같다.

필드생성과 동시에 초기화하는 방법과 생성자를 통해 값을 초기화하는 방법이다. 단순값이라면 생서과 동시에 초기화하고 외부에서 값을 받아와야한다면 생성자에서 초기화 해준다. 

만약 파이널 필드의 초기화를 하지않고 진행하면 에러뜬다, 어떻게든 초기화 할 수 있게 해놓고 넘어가자

상수(static final) 

감이오는가 스테틱이 붙었다. 그냥 불변하는 수라고 생각하자 예를 들어 파이 3.14를 상수라고 한다. 이런 값을 저장하는 필드를 자바에서는 constant라고 부른다. 

도데체 어느 부분이 그냥 파이널과 다른것인가. 인스턴스와 정적멤버의 관계와 비슷하다.

파이널 필드의 경우 객체마다 생성되고 생성자로인해 여러가지 값을 가질수도 있다.

상수인 Static final은 객체마다 저장되지않고 클래스에 포함되어 한번 초기 값을 받으면 변경할수없다. (솔찍히 아직 잘 모르겠다. )


정적 멤버와 마찬가지로 필드생성과 동시에 초기화 하거나 초기화블록을 만들어서 그안에서 초기화 할 수있다.

일반적으로 상수는 대문자로만 작성한다. 단어가 2개이상 조합된다면 _를 이용해 연결한다. 


자바정리와 연습 코드는 모두 신용권 선생님의 "이것이 자바다" 책을 참고하고있다. 

JavaStudy.zip

이전 글에서 다운받으셨다면 그거 지우고 이걸로 교체하시면 편합니다 누가 받겠냐만은..

bin.zip

 


'Java' 카테고리의 다른 글

메소드 재정의(Override)와 몇가지..  (0) 2018.12.12
상속이란?  (0) 2018.12.05
접근 제한자 ,Getter/Setter  (0) 2018.11.22
메소드와 인스턴스멤버, this.  (0) 2018.11.19
자바 개발환경 구축  (0) 2018.10.09