자바(Java) - 클래스 메소드와 인스턴스 메소드

지원·2023년 8월 27일

Java Programming

목록 보기
19/25
  • static이 붙은 메소드 -> 클래스 메소드

  • static이 붙지 않은 메소드 -> 인스턴스 메소드


클래스 메소드 vs 인스턴스 메소드

  • 인스턴스 별로 다르게 동작해야 한다면 인스턴스 메소드

  • static 메소드는 객체 생성이나 유틸리티 관련해서 사용될 때가 있다.

  • 되도록 인스턴스 메소드를 사용한다.


필드(Field)

  • 클래스가 가지는 속성
    - 예를 들어, 사람 이라는 클래스를 만든다면, 태어난 날짜, 이름 등이 필드라고 할 수 있다.

  • 다른 언어에서는 멤버 변수라고 말하는 경우도 있다.

  • 필드는 어떤 키워드와 함께 사용하느냐에 따라 사용 방법이 달라진다.

  • static 키워드와 함께 사용되는 필드 -> 클래스 필드
    함께 사용되지 않는 필드 -> 인스턴스 필드


필드 선언

[접근제한자] [static] [final] 타입 필드명 [=초기값];

  • 대괄호 안에 있는 내용은 생략 가능하다.

  • 접근 제한자는 public, protected, 아무것도 없는 경우(default), private이 올 수 있다.

  • 필드 명은 식별자 규칙을 따른다. ⭐필드는 첫 번째 글자는 소문자로 시작하는 것이 관례이다.

  • 타입(type)은 기본형(boolean, byte, char, short, int, long, float, double)과 참조타입(class, 인터페이스, 배열) 등이 나올 수 있다.

  • 초기값이 없을 경우에, 참조형일 경우 null로 boolean형일 경우 false로 나머지 기본형은 모두 0으로 초기화된다.


필드 선언 예제

String name;
String address = "경기도 고양시";
public int age = 50;
protected boolean flag;
  • String 타입은 참조 타입이다.

  • 접근 제한자가 생략된 name, address는 default 접근 제한자가 설정되었다.


Person class 작성

public class Person {
  String name;
  String address;
  boolean isVip;
}
  • Person 클래스를 실행하기 위해 PersonTest 클래스 생성한다.
public class PersonTest {
  public static void main(String[] args) {
    //p1이라는 변수는 Person 타입을 참조한다. -> 뒤에 '= 참조할 인스턴스'넣어줘야 함
    //Person p1;  p1 = null, 참조하는 것 없이 p1을 사용하면 NullPointException 발생
    
    Person p1 = new Person();

    System.out.println(p1.name);
    System.out.println(p1.address);
    System.out.println(p1.isVip);

  }
}
  • 실행결과
null
null
false


public class PersonTest {
  public static void main(String[] args) {
    //p1이라는 변수는 Person 타입을 참조한다. -> 뒤에 '= 참조할 인스턴스'넣어줘야 함
    //Person p1;  p1 = null, 참조하는 것 없이 p1을 사용하면 NullPointException 발생
    
    Person p1 = new Person();
    Person p2 = new Person();

    p1.name = "홍길동";
    p1.address = "일산";
    p1.isVip = true;
    p2.name = "조조";
    p2.address = "서울";


    System.out.println(p1.name);
    System.out.println(p1.name.length());
    System.out.println(p1.address.length());
    System.out.println(p1.isVip);
    System.out.println("------------------------");
    System.out.println(p2.name);
    System.out.println(p2.name.length());
    System.out.println(p2.address);
    System.out.println(p2.isVip);
   }
}
  • 실행결과
홍길동
3
2
true
------------------------
조조
2
서울
false

p1.name = "홍길동";
p2.name = "조조";

문자열은 new 생성하지 않아도 인스턴스를 생성할 수 있다. 되도록이면 new를 사용하지 않고 큰따옴표로 묶어서 인스턴스를 참조하는 것이 좋다.

왜? `String`을 너무 많이 쓰니까 큰따옴표만으로도 사용할 수 있게 하였다.

클래스 필드를 Person 클래스에 추가

public class Person {
  String name;
  String address;
  boolean isVip;
  static int count = 0;
  
  public void printName(){
  	System.out.println("내 이름은" + name);
  }
  
  public static void printCount() {
  	System.out.println("count : " + count);
  }
}
  • 메소드는 클래스에서 선언된 필드를 사용할 수도 있다.

  • printName메소드는 Person클래스가 만들어져야 사용할 수 있고, printCount메소드는 인스턴스를 생성하지 않아도 클래스명.메소드명()으로 사용 가능하다.

  • static이 붙어있지 않은 필드 = 인스턴스 필드
    -> 인스턴스를 만들어야만 사용 가능하다.

  • static이 붙어있는 필드 = 클래스 필드

  • Person 인스턴스가 생성될 때 count 변수가 생성될까?
public class PersonTest2 {
  public static void main(String[] args) {
    Person p1 = new Person(); // Person 인스턴스 생성
    Person p2 = new Person();

    p1.name = "홍길동";
    p2.name = "조조";

    System.out.println(p1.name);
    System.out.println(p2.name);
    System.out.println(p1.count);
    System.out.println(p2.count);
    p1.count++;
    System.out.println(p1.count);
    System.out.println(p2.count); //p2는 count 늘리지 않았는데 1 출력
    p2.count++;
    System.out.println(p1.count);
    System.out.println(p2.count);
  }
}
  • 실행결과
홍길동
조조
0
0
1
1
2
2
  • Person p1 = new Person();은 Person 인스턴스를 생성한다. 그런데 인스턴스를 만들기 전에 JVM이 하는 일이 있다.
    -> JVM은 Person 클래스가 CLASSPATH에 있는지 찾아보고 클래스를 찾을 수 없다면 ClassNotFoundException 오류를 발생한다.

  • 예를 들어, Person 클래스와 PersonTest2 클래스를 만든 사람이 서로 다른 사람이라고 가정하자.
    -> PersonTest2 클래스를 실행하면, Person 클래스를 찾게 되고 Person 클래스를 찾으면 Person 클래스 정보를 메모리에 올리게 된다.
    ⭐클래스 정보 자체는 정적이다. 클래스 정보 자체는 실행되는 것이 아니므로

-> 클래스 정보를 메모리에 올리게 되는데, 이때 클래스에 static 필드가 있는지 살펴본다.
static한 필드를 갖고 있으면 정적 영역에 따로 저장된다.
Person이 가지고 있는 count 변수는 별도로 저장되고 0으로 초기화된다.
즉, count 변수는 인스턴스 별로 가지는 것이 아니라 정적 영역에 따로 관리된다.

  • static한 필드는 클래스명.필드명형식으로 사용한다.
    static 필드 = 클래스 변수
public class PersonTest3 {
	public static void main(String[] args) {
    	Person p1 = new Person();
        p1.name = "홍길동";
        
        p1.printName();
        p1.printCount();
        
        Person.count++;
        p1.printCount();
	}
}
  • 클래스가 가지고 있는 메소드는 자신이 갖고 있는 필드들을 사용할 수 있다.

  • 하지만, static한 메소드는

    Person.printCount();
     Person.count++;

    이런 식으로 작성하는 것이 좋다.

  • JVM은 Person 클래스 정보를 읽어들일 때 Person이 가지고 있는 클래스 필드와 클래스 메소드를 사용 가능하도록 메모리에 올린다.

  • 인스턴스 필드와 인스턴스 메소드는 인스턴스를 생성한 후, 그 인스턴스를 참조하는 참조 변수를 이용해서 사용해야 한다.

  • static한 메소드에서는 인스턴스 필드나, 인스턴스 메소드를 사용할 수 없다. 왜냐하면, 메모리에 생성되는 시점이 다르기 때문이다.
    클래스 메소드는 인스턴스가 없어도 사용 가능하지만 인스턴스 필드는 인스턴스가 있어야만 사용하기 때문이다.

profile
우주 정복자

0개의 댓글