12일차 instance멤버와 static멤버

쿠우·2022년 4월 7일
0

인스턴스 멤버

인스턴스 멤버란?

(1)객체(인스턴스) 마다 가지고 있는 필드와 메소드
-이들을 각각 인스턴스 필드, 인스턴스 메소드라고 부름

(2)인스턴스 멤버는 객체 소속된 멤버이기 때문에 객체가 없이 사용불가

정적 멤버와 static

정적(static) 멤버란?

(1)클래스에 고정된 필드와 메소드 - 정적 필드, 정적 메소드

(2)정적 멤버는 클래스에 소속된 멤버
-객체 내부에 존재하지 않고, 메소드 영역에 존재
-정적 멤버는 객체를 생성하지 않고 클래스로 바로 접근해 사용

정적 멤버 선언

(1)필드 또는 메소드 선언할 때 static 키워드 붙임

--------------------------------정적 멤버선언---------------------------------
public class Calculator {
	
	static double pi = 3.14159;
	
	static int plus(int x, int y) {
		return x + y; 
	}//plus
	
	
	static int minus(int x, int y) {
		return x - y;
		
	}//minus
	
	
		
}//end class

정적 멤버 사용

(1)클래스 이름과 함께 도트(.) 연산자로 접근

----------------------------정적 클래스 멤버 사용 -------------------------------
public class CalculatorEx {

	//대전제 : 정적멤버(필드와 메소드)는 정적멤버답게 사용하라!!
	// 		   클래스명.필드 또는 클래스명.메소드 호출해라!!
	public static void main(String[] args) {
		// 전자계산기 클래스의 정적필드인 원주율(pi)은, 
		// 어디에서건 공용으로 사용할 수 있도록 하기 위해, static을 붙여 
		// 정적필드로 선언
		double result1 = 10 * 10 * Calculator.pi;
		
		// 아래의 전자계산기 메소드도, 위와 같은 이유, 즉 어디에서건 공유해서 
		// 사용할만 한 행위(=기능)이라고 판단하였기 때문에, 정적 메소드로 선언 
		int result2 = Calculator.plus(10, 5);
		int result3 = Calculator.minus(10, 5);
		
		System.out.println("result1 :" + result1);
		System.out.println("result2 :" + result2);
		System.out.println("result3 :" + result3);
		
	}// main

} // end class

인스턴스 멤버 선언 vs 정적 멤버 선언의 기준

(1)필드
-객체 마다 가지고 있어야 할 데이터 > 인스턴스 필드
-공용적인 데이터 > 정적 필드

(2)메소드
-인스턴스 필드로 작업해야 할 메소드 > 인스턴스 메소드
-인스턴스 필드로 작업하지 않는 메소드 > 정적 메소드

-------------------인스턴스 정적의 멤버 선언의 기준 --------------------------
import lombok.NoArgsConstructor;

@NoArgsConstructor
public class Person2 {
	
	String colorOfEyes; // 눈동자의 색깔 
	int numberOfEyes = 2; // 눈동자의 개수 
	
	String name; //이름
	int age; 	 //나이
	
	String colorOfHairs; // 머리카락 색상
	int numberOfArgs=2;// 팔의 개수 
	
	
	// 구현한 기능(행위)가, 모든 객체에 공통적으로 
	// 적용할 수 있게 구현되었다면 , 정적멤버로 선언한다.
	// 구현할 공통기능 기준을 어떻게 잡는지에 따라 다르다.
	void eat() { 	 // 먹다! //먹는 방식이 다를 수도 있다
		;;
	} //eat
	
	void walk() { 	// 걷다!  
		;;
	}//walk
	

}//end class

-------------------------정적필드와 인스턴스 필드의 구분 -----------------------
@Setter
@RequiredArgsConstructor //필수적으로 인자값을 갖어야만 하는 필드값을 채울 수 있는 생성자를 만들어라 
public class Car {
	
	//클래스의 모든 구성 멤버 선언시, 'static'이란 키워드가 있느냐/없느냐에 따라 
	//인스턴스멤버(static 키워드 없음)와 정적멤버(static 키워드 있음)로 나뉜다.
	//클래스가 만든 많은 객체의 멤버들 중 속성과 기능이 공통이어야하는 것들을 정적멤버로 만든다.
	@NonNull String model; 
	static int initialspeed;
	int speed;

	String color;
	int door; // final int door =4; 가 더 어울리는 값이다.
	
	
	// door는 차문이 4개로 보편적인 공통 속성이기 때문에 공통된 상수로 만드는 것이 좋다.  
	// Case1 : model ="아반테" , door=1;
	// Case2 : model ="제네시스" , door =4;
	// Case3 : model ="싼타페" , door =8;
	public Car(String model, int door) {
		this.model = model;
	}// constructor
	
	
	
	
	
	
	void run() {
		for(int i=10; i<=50; i+=10) {
			this.setSpeed(i);
			System.out.println(this.model + "가 달립니다.(시속:" + this.speed +"km/h");
		}//for
	}//run
	
	
}// car

Static 멤버의 소속이 어디있는 것인가?

clazz --> 메소드 영역에서의 각 클래스의 바이트코드를 저장하고 있는 객체

static 멤버는 clazz 객체 안에 생깁니다.

파일명.class ---> [ClassLoader] ---> Clazz 객체생성 --->메소드 영역으로 꽂아 넣음

나의 이해 * static 멤버는 메소드 영역으로 가서 clazz라는 객체로 class의 본질적인 주소를 가지고 저장되고 거기서 생성된 객체들은 힙영역으로가서 주소를 가진다

*구굴링: 클래스 로더 시스템은 바이트 코드를 BootStrap, Extension, Application 3가지의 클래스 로더로 로딩하여
링크로 코드 내부의 레퍼런스를 연결하고 추가적으로 static 변수는 초기화 과정까지 거쳐
실행 엔진이 사용할 수 있도록 JVM 메모리의 메서드 영역에 적재하는 시스템이다.


정적 초기화 블록

(1)클래스가 메소드 영역으로 로딩될 때 자동으로 실행하는 블록
(2)정적 필드의 복잡한 초기화 작업과 정적 메소드 호출 가능
(3)클래스 내부에 여러 개가 선언되면 선언된 순서대로 실행

---------------------------인스턴스와 static 멤버의 관계와 초기화 방법-------------------------------------
package instanceex;

public class TTTT {

	public static void main(String ... args) {
		Student student = new Student();
		
		System.out.println("1. student: " + student);
		
		
		//인스턴스 메소드 호출 
		student.instanceMethod();
		
		//정적 메소드호출 
		student.staticMethod(); //대전제 1. 지키지 않았다. warring
		Student.staticMethod(); 
		
	}// main
}//end class


//-------------




// 대전제1: 정적멤버는 정적멤버답게 사용하라!(타입명.멤버)
// 대전제2: this라는 키워드 오로지 인스턴스 메소드안에서만 사용가능!
// 대전제3: 인스턴스 멤버는 다른 인스턴스 멤버 + 정적멤버까지 모두 사용가능!
//           정적 멤버는 오로지 다른 정적멤버만 사용가능!!


class Student {
	
	{
		System.out.println("User-defined bolck inboked!");
		
	} // 사용자 정의 블록 (User - define block) 
	
	
	static {
		System.out.println("Student::static initializer inboked!");
		
		staticField =200;
		staticField2=300;
	
		{
			System.out.println("User-defined bolck#6 inboked!------Static block 안에서" );
		} // 사용자 정의 블록 (User - define block) #6  

	} //static initializer  --> static 초기화 블럭
	
	
	Student innerStudent = this ; 
//	static Student staticStudent =this ;  안된다.
	
	
	
	int instanceField;         //인스턴스 필드 
	static int staticField;    // 정적 필드  --> 객체하고 전혀 상관없는 존재다. 클래스에 같이 박혀있음.
	static int staticField2;
	
	// static 초기화블럭 역할: static 필드 초기화 하는 곳
	
	// new 연산자가 생성한 초기화되지 않은 객체를 초기화 하는 역할
	// 생성자의 역할 : 인스턴스필드의 초기화를 하는곳!
	Student(){
		System.out.println("Student::default constructor invoked.");
		instanceField = 100;  //OK
		staticField =200;  	  // OK: NOT REconmmented (되긴하는데 여기서 하지 않는다.)
	} // Constructor
	
	
	static {
		System.out.println("Student::static initializer#2 inboked!");
	}// static initializer #2
	
	
	{
		System.out.println("User-defined bolck#2 inboked!");
	} // 사용자 정의 블록 (User - define block) #2
	

	void instanceMethod() {
		System.out.println("2. Student::instanceMethod() invoked.");

		//this: 
		// (1) 클래스 블록 내에서만 사용가능하다!
		// (2) 이 클래스의 인스턴스(객체)의 주소를 가지고 있고,
		// 	   이 주소는 참조변수에 저장된 객체의 주소와 같다!
		System.out.println("\t + this: " + this); // \들여쓰기
		System.out.println("\t + innerStudent: "+ innerStudent);
		System.out.println("\t + staticField: "+ Student.staticField); //클래스명 반드시 표기 구분안가!
		
		
		//다른 정적메소드 호출
		Student.staticMethod();
		
		
		{
			System.out.println("User-defined bolck#4 inboked!------static 메서드 안에서" );
		} // 사용자 정의 블록 (User - define block) #4   
		
	}// instanceMethod
	
	
	static void staticMethod() {
		System.out.println("Student::staticMethod() invoked.");
		
		//대전제 1과 3적용
		System.out.println("\t + staticField: "+ staticField2);
		
		
//		System.out.println("\t + this: " + this); static 에 인스턴스인 this 놉
		
//		instanceMethod(); << 인스턴스 메서드 놉
		
		{
			System.out.println("User-defined bolck#5 inboked!------인스턴스 메서드 안에서" );
		} // 사용자 정의 블록 (User - define block) #5   
		
		
	}// staticMethod 
	
	
	
	static {
		System.out.println("Student::static initializer#3 inboked!");
		
//		System.out.println("\t + this: " + this); static 에 인스턴스인 this 놉
		
	}// static initializer #3 --> 여러개 어디서든 선언가능 //보통 맨 위에
	// static 초기화 블럭은 객체가 생성되기 이전에 가장 우선적으로 수행된다. 
	//단 이들끼리는 위에서부터 순서를가진다 
	
	{
		System.out.println("User-defined bolck#3 inboked!");
	} // 사용자 정의 블록 (User - define block) #3  --> 여러개 어디서든 선언가능 
	//  클래스 영역에 있는 것이 아니면 
	
	
}// end class
profile
일단 흐자

2개의 댓글

comment-user-thumbnail
2022년 4월 7일

강사님이 하시는 대로 따라서 적었더니 코드 엄청 많아졌다.. 올리면서 뭐가 뭔지 다시 한 번 보니까 11시..

답글 달기
comment-user-thumbnail
2022년 4월 7일

오늘이 뭔가 제일 머리 아팠다.... 너무 재밌다 이 고통...

답글 달기

관련 채용 정보