▶ 용어짚고가기
객체(object)는 속성과 행동으로 구성되어 있는 하나의 단위이다. 궁극적인 실체이다.
클래스(class)는 객체를 만드는 설계도이다. 어느 무리의 객체를 특징 짓는 데에 공통적으로 갖춘 모양을 뽑아서 하나의 틀을 만든 것이다. 이런 과정을 '추상화'라고 한다.
인스턴스(instance)는 클래스를 new 명령문으로 메모리에 생성한 객체이다. 설계도를 통해 독립적인 객체를 만든 것이다.
/* 객체와 인스턴스 */
public class Animal {
public class Main {
public static void main(String[] args) {
Animal cat, dog; // '객체'
// 인스턴스화
cat = new Animal(); //cat은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당)
dog = new Animal(); // dog은 Animal 클래스의 '인스턴스'(객체를 메모리에 할당) } } }
즉, 우리가 프로그래밍으로 표현하려는 실체는 객체이고, 이러한 실체를 추상화한 설계도는 클래스이며, 클래스를 인스턴스화하여 객체가 생성되는 것이다.
※변수의 종류
클래스 영역에 선언되어 있으면 멤버변수
메서드 내부에 선언되어 있으면 지역변수
멤버변수 중 static이 붙은 것은 클래스 변수,
붙지 않은 것은 인스턴스 변수
1. 클래스변수 (아래에서 거하게 설명할꺼임)
- 모든 객체가 공유하는 변수, 클래스차원에서 단 하나만 생성
- 클래스 이름으로 접근
- 클래스가 로딩될 때 생성되어 프로그램이 종료될 때까지 유지됨
- 디폴트값으로 초기화됨
2. 인스턴스변수
- 클래스 영역에서 선언된 변수
- 클래스의 인스턴스를 생성할 때 만들어짐
- 객체끼리 필드는 각자 따로 가지고, 메서드는 공유함
- 디폴트값으로 초기화함 -> 명시적 초기화 -> 생성자
- 참조되지 않는 변수는 garbage collector에 의해 소멸됨
3. 지역변수
- 메서드 내부에서만 사용 가능한 지역변수, 메서드 내에서 선언되는 변수
- 메서드가 시작될 때 생성
- 메서드를 빠져나갈 때 사라짐
※ static 변수
=클래스 변수
- 개별객체에 소속 XXXXXXX (= 이건 인스턴스 변수가 하는 짓) 클래스에 직접 소속 !!
- 객체가 아무리 많이 생성되어도 static 변수는 단 하나만 생성되며, 객체가 전혀 없어도 하나는 생성됨
- 메모리에 딱 한번만 생성되며 모든 객체가 공유함
따라서 어떤 객체에서 static 변수 변경 시 모든 객체에 영향 有
▷ 이럴때 static 변수로 선언합니다 !
1. 클래스의 모든 객체들이 공유해야하는 설정정보
2. 읽기만 하는 참고 정보
3. 필드(=멤버변수) 영역마다 같은 값을 가지는 필드가 있어야 할 경우
- 각 영역마다 필드를 만들필요 없이, static 변수로 선언해서 사용
▷ static 으로 선언하면 이런게 가능해집니다 !
1. 클래스 차원에서 바로 호출이 가능
2. 클래스에 대한 인스턴스를 생성하지 않아도 해당 클래스의 메서드를 호출해서 사용할 수 있음
3. 클래스의 이름으로만 접근가능 => 클래스의 이름으로 접근
4. static 변수는 클래스가 메모리에 로드될 때 생성됨 ( = 태초부터 존재 )
▼ static 사용예시
- static 변수는 메모리를 공유한다
class Number{
static int num = 0; // static 멤버변수
int num2 = 0; // 인스턴스 멤버변수
}
public class StaticTest{
Number number1 = new Number(); //첫번째 number
Number number2 = new Number(); //두번쨰 number
number1.num++; //클래스 필드 num을 1증가시킴
number1.num2++; //인스턴스 필드 num을 1증가시킴
System.out.println(number2.num); //두번째 number의 static 필드 출력
System.out.println(number2.num2);//두번째 number의 인스턴스 필드 출력
}
}
=> 1
0
똑같이 ++ 를 했을 때
static 인 num 은 1 이 나왔으나
인스턴스인 num2 는 0 이나왔다.
왜일까 ?
인스턴스 변수는 인스턴스(객체) 가 생성될 때마다 생성되므로 각기 다른값을 가지지만
static 변수는 모든 인스턴스가 하나의 저장공간을 공유하기때문에 항상 같은 값을 가지기 때문
▼ static 사용예시 2
- static 메서드는 객체생성(=new 어쩌구) 를 하지 않아도 호출이 가능하다
class Name{
static void print() { //클래스 메소드
System.out.println("내 이름은 홍길동입니다.");
}
void print2() { //인스턴스 메소드
System.out.println("내 이름은 이순신입니다.");
}
}
public class Static_ex {
public static void main(String[] args) {
Name.print(); //객체생성하지 않아도 호출이 가능
Name name = new Name(); //인스턴스 생성
name.print2(); //객체를 생성하여야만 호출이 가능
}
}
▶ static 변수 (=클래스 변수) 의 초기화 시점
- JVM에 의해서 클래스가 메모리 공간 에 올라가는 순간임
- 초기화 순서: default값 => 명시적 초기화 => static 초기화 블럭
▶ 인스턴스(=객체 변수) 변수의 초기화 시점
- 인스턴스가 생성될 때마다 각 인스턴스별로 초기화가 이루어짐
- 초기화 순서: default 값 = > 명시적 초기화 => 생성자
= > static 변수는 항상 인스턴스 변수보다 먼저 생성되고 초기화됨!!
▽ 요렇게
* static method : 1
* static block : 2
* static method : 3
* instance method : 4
* instance block : 5
* instance method : 6
* contsructor : 7
* instance method : 8
* instance block : 9
* instance method : 10
* contsructor : 11
※ static 초기화 블럭 (=클래스 초기화 블럭)
- static 변수의 복잡한 초기화에 사용됨
- 해당 클래스가 메모리에 로딩될 때 한번만 수행됨
( 해당 클래스가 메모리에 로딩될 때 static 변수들이 메모리에 만들어지고,
바로 static 초기화 블럭이 수행되서 static 변수들을 초기화하게 됨 )
- default값 > 명시적 초기화 > 스태틱 초기화 블럭
static {
}
static 초기화 블럭 내가 쉽게 정의하기 :
- static 변수나 static 메서드는 인스턴스화 (=new 어쩌구) 없이도 호출하거나 참조할 수 있는 요긴한 놈.
이 요긴한 놈을 사용하려면 미리 초기화해놓는게 좋다.
'선언' 처럼 값을 지정해버리면 될 일이지만,
복잡한 초기화를 해야하는 경우 !
ex ) 조건문, 반복문, 예외처리 구문 등 명시적 초기화만으로는 부족한 경우
>> 초기화 블럭을 이용한다 <<
package com.day13.sub;
class StaticBlock{
static int[]arr=new int[10]; //명시적 초기화
//static 초기화 블럭
static {
for(int i=0;i<arr.length;i++) {
arr[i]=(int)(Math.random()*10+1);
}//for
}
}
public class StaticBlockTest {
public static void main(String[] args) {
for(int i=0;i<StaticBlock.arr.length;i++) {
System.out.println(StaticBlock.arr[i]);
}
}
}
※Static 메서드
- 자주 사용하는 메서드인 경우 메서드 하나를 사용하기 위해서 매번 큰 인스턴스 전체를 메모리에 load하는 것은 비효율적이다 따라서 static변수로 선언해서 인스턴스 없이 바로 클래스 차원에서 호출 해서 사용
- static 메서드는 static 데이터만 접근 가능, 인스턴스변수에 접근 불가
- static 메서드에서는 static 멤버변수만 사용가능
- non-static 데이터는 new로 클래스를 인스턴스화 (=객체생성 ) 시킨 후 접근해야 함
- main() 메서드는 static 메서드 (객체를 만들기 전에 호출되어야 하므로)
※this
- 자기 자신을 가리키는 this (자신의 멤버를 가리키는 this => this.멤버변수 )
- 인스턴스(=객체) 자신을 가리키는 참조변수
- 인스턴스의 주소가 저장됨
- 클래스를 디자인할 때 사용, 객체 생성 후 사용하는 것이 아님
- 객체를 생성하기 전 단계의 그 주소를 this 라 칭하고, 할당되는 순간
this 에게 할당된 메모리의 주소값(참조값)을 넘겨줌
- Static 에서는 사용할 수 없다
- this 를 이용하면 생성자 만들때 굳이 다른 이름을 사용할 필요가 없다
//생성자 안만들었어도 ()안에 Stirng -- 에서 "--"은 다른것으로 써야함 name!=p_name 이렇게
// 근데 좀 불편하지 않냐며.. 그래서 this 키워드 有
// 자기자신을 가리키는 'this'
'JAVA' 카테고리의 다른 글
[JAVA] 상속 / 오버라이딩 / this,super / 검색하기 (0) | 2022.02.26 |
---|---|
[JAVA] 클래스배열 (0) | 2022.02.24 |
[JAVA] 생성자 / 접근제한자 / getter,setter (0) | 2022.02.22 |
[JAVA] 객체와 클래스 (0) | 2022.02.21 |
[JAVA] 배열 (0) | 2022.02.19 |