Java static vs 인스턴스 멤버

별의개발자커비·2023년 2월 11일
0

Java

목록 보기
26/66
post-thumbnail

참고글

[java] 클래스변수, 인스턴스 변수 차이(static변수와 non Static변수)

인스턴스 멤버( static 이 안 붙으면 다 / 정적 )

: 각자 갖고 있는 메뉴판

  • 인스턴스 변수
  • 인스턴스 메소드

static 멤버

: 가게 벽에 걸려있는 다 같이 볼 수 있는 메뉴판

  • static 변수 (=클래스 변수 = Static Field )
  • static 메소드
  • 객체를 통해 사용하지는 않고, 클래스 이름 자체로 사용함
    --> 객체를 안 만들고 클래스 속 변수나 메소드를 사용할 수 있다.
  • static 변수(클래스 변수)는 클래스에 소속되어 같은 클래스 관련 모든 메소드에서 이 값을 가져올 수 있게 된다.
  • static final 상수 = 초기값;
    (더 이상 수정할 수 없음 그래서 바로 초기화 해야 함)

1. 개념 코드

클래스 파일

public class Circle {
	static int circleMaxNum = 100 ; // 정적 멤버 변수 
	
	public static final int MAXCIRCLENUM = 200; // 1.
	public final int MAXCIRCLENUM2 = 200; // 2. 따라서 final에는 static 자동 붙여라
	// 위 두개의 차이는 1. static 이 붙으면 demo 파일에서 굳이 2. circle c 객체 만들어서 c.max로 부를 필요 없이, 그냥 circle.max로 클래스로 부를 수 있음
	// static은 이런 변수도 되지만 메소드에 붙여도 됨
	
	private static double radius ; 		// 인스턴스 멤버 변수 (static 안 붙은 애들은 다)
	

	public Circle(double d) {
		this.radius = radius ;
	}

	public double getRadius() {
		return radius;
	}

	// 생성자를 통해서 radius 셋팅한다의 뜻은 이거다
	public void setRadius(double radius) { // 매개변수 생성자 ?? 이거 이해해야해
		this.radius = radius;
	}
	
	
	
	// 인스턴스 메소드 : 안에서는 static 정적 요소를 사용할 수 있음
	public double getSize() {
		System.out.println(MAXCIRCLENUM); // static 변수도 잘 써지네?
		return radius * radius * 3.14 ; 
	}
	
	// 정적 메소드 : 안에서는 인스턴스 요소를 사용할 수 없다.
	public static double getSize2() { // ??어차피 static인데 public 써줘야하나?
		System.out.println(MAXCIRCLENUM); // MAXCIRCLENUM2는 인스턴스라 안된다
		return radius * radius * 3.14 ; 
	}
	
	// static 은 끼리끼리 논다... 나쁜 애들ㅋㅋ 
// static 정적 메소드 : 안에서는 인스턴스 요소를 사용할 수 없다. 의 이유는?
  • 메모리 생성 순서
    : static -> 인스턴스 --- 따라서 저 안(static)에서 radius(인스턴스)는 아직 생성되지 않아서

Demo 파일

public class CircleDemo {

	public static void main(String[] args) {
		// static 멤버 호출
		System.out.println(Circle.circleMaxNum ); // static 멤버 변수라, 클래스를 객체로 안 만들고도 호출 가능! -- 객체 만들 때마다 메모리 차지하니 절약!
		
		// 인스턴스 멤버 호출 : 객체를 통해서 ( 즉, 객체생성)
		Circle c = new Circle();
		c.setRadius(2.36);
		
//		c.MAXCIRCLENUM = 20; // error -- 아래 같은 일들은 할 수 있지만..
		int temp = c.MAXCIRCLENUM ;
		System.out.println(c.MAXCIRCLENUM);
		
		Circle c2 = new Circle();
		System.out.println(c2.MAXCIRCLENUM);
		System.out.println(Circle.circleMaxNum);
		


	}
public class CircleDemo2 {

	public static void main(String[] args) {
		Circle c = new Circle(3.5);
		
		
		// 생성자를 통해서 radius 셋팅하고 getSize의 반환값 출력하기
		c.setRadius(6);
		System.out.println(c.getSize());
		System.out.println(Circle.getSize2());

	}

}

2. 응용하면 이런 코드도!

클래스 파일

package lesson7;

public class Tv {
	// 변수 channel , volume , serialNumber 1 2 3 4 5 6 
	// 메소드 volumeUp, volumeDown, channelUp, channelDown
	

//	public static int channel ;
//	public static int volume ; 
	
	public static int count = 0  ; // static이니까 demo의 모든 객체가 같이 쓰는 애들 

	
	private int channel, volume, serialNumber=0;
	

	public Tv() { // 얘는 생성자라 초기에 항상 실행되는 애
		count++ ; // @@오오 얘를 추가하고 아래에 count를 대입하니까 시리얼넘버가 하나씩 증가하네? 원래는 tv1,2 다 1이었는데
		serialNumber = count ; // 여기에 이걸 넣어주면 객체가 t1,2, 생길 때마다 시리얼 넘버가 생김
	}
	
	
	
	
	public int getChannel() {
		return channel;
	}
	public void setChannel(int channel) {
		this.channel = channel;
	}
	public int getSerialNumber() {
		return serialNumber;
	}
	public void setSerialNumber(int serialNumber) {
		this.serialNumber = serialNumber;
	}
	public int getVolume() {
		return volume;
	}
	public void setVolume(int volume) {
		this.volume = volume;
	}

	
	public void volumeUp() {
		volume++;
	}
	public void volumeDown() {
		volume--;
	}
	public void channelUp() {
		channel++;
	}
	public void channelDown() {
		channel--;
	}

}

Demo 파일

package lesson7;

public class TvDemo {

	public static void main(String[] args) {
		// 객체 생성될 때 마다 시리얼 넘버를 하나씩 올려 넣어주려면 어떻게 해야할까?
		Tv t = new Tv() ;
		t.setVolume(20);
		t.volumeUp();
		System.out.println(t.getVolume());

		Tv t2 = new Tv() ;
		System.out.println(t2.getVolume());

		System.out.println(t.getSerialNumber());
		System.out.println(t2.getSerialNumber());

	}

}

* 이해를 위한 추가 모든 경우 코드

class C1{
    static int static_variable = 1;
    int instance_variable = 2;
    static void static_static(){
        System.out.println(static_variable);
    }
    static void static_instance(){
        // 클래스 메소드에서는 인스턴스 변수에 접근 할 수 없다.
        System.out.println(instance_variable);
    }
    void instance_static(){
        // 인스턴스 메소드에서는 클래스 변수에 접근 할 수 있다.
        System.out.println(static_variable);
    }
    void instance_instance(){
        System.out.println(instance_variable);
    }
}

class Main {

    public static void main(String[] args) {
        C1 c = new C1();
        // 인스턴스를 이용해서 정적 메소드에 접근 -> 성공
        // 인스턴스 메소드가 정적 변수에 접근 -> 성공
        c.static_static();
        // 인스턴스를 이용해서 정적 메소드에 접근 -> 성공
        // 정적 메소드가 인스턴스 변수에 접근 -> 실패
        c.static_instance();
        // 인스턴스를 이용해서 인스턴스 메소드에 접근 -> 성공
        // 인스턴스 메소드가 클래스 변수에 접근 -> 성공
        c.instance_static();
        // 인스턴스를 이용해서 인스턴스 메소드에 접근 -> 성공
        // 인스턴스 메소드가 인스턴스 변수에 접근 -> 성공
        c.instance_instance();
        // 클래스를 이용해서 클래스 메소드에 접근 -> 성공
        // 클래스 메소드가 클래스 변수에 접근 -> 성공
        C1.static_static();
        // 클래스를 이용해서 클래스 메소드에 접근 -> 성공
        // 클래스 메소드가 인스턴스 변수에 접근 -> 실패 
        // @@ 여기서 부터 다 실패는 인스턴스는 생성된 적이 없는데 인스턴스 메소드에 접근하려고 한 것이기 때문에
        C1.static_instance(); 
        // 클래스를 이용해서 인스턴스 메소드에 접근 -> 실패
        //C1.instance_static();
        // 클래스를 이용해서 인스턴스 메소드에 접근 -> 실패
        //C1.instance_instance();
    }
}

(출처 생활코딩 바로실습 https://edu.goorm.io/learn/lecture/41/%EB%B0%94%EB%A1%9C%EC%8B%A4%EC%8A%B5-%EC%83%9D%ED%99%9C%EC%BD%94%EB%94%A9-%EC%9E%90%EB%B0%94-java/lesson/693/%EB%A7%B4%EB%B2%84%ED%83%80%EC%9E%85%EC%9D%98-%EB%B9%84%EA%B5%90)

0개의 댓글