Don't Panic
in Java ☕ 4분 읽기

[Java] java 인스턴스

목차

05. 인스턴스 생성과 힙 메모리 (heap memory)

인스턴스 (instance)

  • 클래스는 객체의 속성을 정의하고 기능을 구현하여 만들어 놓은 코드 상태다.
  • 클래스를 기반으로 생성된 객체(인스턴스)는 각각 다른 멤버 변수 값을 가진다.
    • 가령, 학생 클래스에서 생성된 각각의 인스턴스는 서로 다른 이름, 학번, 학년 등의 값을 가진다.
  • new 키워드를 사용하여 인스턴스를 생성하면 동적 메모리에 생성된다.
    • 참고로 C++은 delete, C는 free로 해제한다.

힙 메모리

  • 생성된 인스턴스는 동적 메모리(heap memory)에 할당된다.
  • C나 C++ 언어에서는 사용한 동적 메모리를 프로그래머가 직접 해제해야 한다. (free()delete 이용)
  • 자바에서는 Garbage Collector가 주기적으로 사용하지 않는 메모리를 수거한다.
  • 하나의 클래스로부터 여러 개의 인스턴스가 생성되며, 각각 다른 메모리 주소를 가진다.

힙 메모리에 할당되는 인스턴스

참조 변수, 참조 값

package ch04;

public class StudentTest {

public static void main(String[] args) {

  Student studentLee = new Student();
  studentLee.studentName = "이순신";
  studentLee.address = "서울";


  studentLee.showStudentInfo();

  Student studentKim = new Student();
  studentKim.studentName = "김유신";
  studentKim.address = "경주";

  studentKim.showStudentInfo();

  System.out.println(studentLee);
  System.out.println(studentKim);
}

}

참조 변수 출력 결과

출력 결과에서 앞부분은 패키지 이름과 클래스 이름(클래스 풀네임)이고, 뒤는 주소 값(레퍼런스 값)이다. 즉, 참조 변수가 가리키는 인스턴스의 주소를 의미한다.

용어 정리

용어설명
객체객체 지향 프로그램의 대상, 생성된 인스턴스
클래스객체를 프로그래밍하기 위해 코드로 정의해 놓은 상태
인스턴스new 키워드를 사용하여 클래스를 메모리에 생성한 상태
멤버 변수클래스의 속성, 특성
메서드멤버 변수를 이용하여 클래스의 기능을 구현한 함수
참조 변수메모리에 생성된 인스턴스를 가리키는 변수
참조 값생성된 인스턴스의 메모리 주소 값

06. 생성자에 대해 알아봅시다 (constructor)

생성자

생성자 기본 문법은 다음과 같다.

<modifier><class_name>([<argument_list])
{
	[<statements]
}

Student lee = new Student()에서 new 뒤가 생성자, lee가 인스턴스다. primitive 타입을 제외한 객체는 전부 생성자를 사용해야 한다.

  • 객체를 생성할 때 new 키워드와 함께 사용한다. (예: new Student();)
  • 생성자는 일반 함수처럼 기능을 호출하는 것이 아니라, 객체를 생성하기 위해 new와 함께 호출된다.
  • 객체가 생성될 때 변수나 상수를 초기화하거나, 다른 초기화 기능을 수행하는 메서드를 호출한다.
  • 생성자는 반환 값이 없고, 클래스의 이름과 동일하다.
  • 대부분의 생성자는 외부에서 접근 가능하지만, 필요에 따라 private으로 선언되는 경우도 있다.

기본 생성자 (default constructor)

  • 클래스에는 반드시 적어도 하나 이상의 생성자가 존재한다.
  • 클래스에 생성자를 구현하지 않아도 new 키워드와 함께 생성자를 호출할 수 있다.
  • 클래스에 생성자가 하나도 없는 경우, 컴파일러가 생성자 코드를 넣어 준다.
public Student(){}  
  • 매개 변수가 없고, 구현부가 없다.

생성자 만들기

컴파일러가 제공해 주는 기본 생성자 외에, 필요에 따라 생성자를 직접 구현할 수 있다.

Student.java

public class Student {

	public int studentNumber;
	public String studentName;
	public int grade;

	public Student(int studentNumber, String studentName, int grade) {
		this.studentNumber = studentNumber;
		this.studentName = studentName;
		this.grade = grade;
	}

	public String showStudentInfo() {
		return studentName + "학생의 학번은 " + studentNumber + "이고, " + grade + "학년 입니다.";
	}
}

StudentTest.java

public class StudentTest {

	public static void main(String[] args) {

		//Student studentLee = new Student();

		Student studentLee = new Student(12345, "Lee", 3);

		String data = studentLee.showStudentInfo();
		System.out.println(data);
	}

}

07. 여러 가지 생성자를 정의하는 생성자 오버로딩 (overloading)

생성자 정의하기

  • 생성자를 여러 개 구현해서 사용할 수 있다.
  • 클래스에 생성자를 따로 구현하면 기본 생성자(default constructor)는 제공되지 않는다.
  • 생성자를 호출하는 코드(client 코드)에서 여러 생성자 중 필요에 따라 골라서 호출할 수 있다.

UserInfo.java

public class UserInfo {

	public String userId;
	public String userPassWord;
	public String userName;
	public String userAddress;
	public String phoneNumber;

	public UserInfo(){}

	public UserInfo(String userId, String userPassWord, String userName) {
		this.userId = userId;
		this.userPassWord = userPassWord;
		this.userName = userName;
	}

	public String showUserInfo() {
		return "고객님의 아이디는 " + userId + "이고, 등록된 이름은 " + userName + "입니다.";
	}
}

UserInfoTest.java

public class UserInfoTest {

	public static void main(String[] args) {

		UserInfo userLee = new UserInfo();
		userLee.userId = "a12345";
		userLee.userPassWord = "zxcvbn12345";
		userLee.userName = "Lee";
		userLee.phoneNumber = "01034556699";
		userLee.userAddress = "Seoul, Korea";

		System.out.println(userLee.showUserInfo());

		UserInfo userKim = new UserInfo("b12345", "09876mnbvc", "Kim");
		System.out.println(userKim.showUserInfo());
	}
}

08. 복습해봅시다 (객체 구현하기)

다음 설명에 해당되는 객체를 구현하고 해당 정보를 출력해 보세요

  1. 키가 180이고 몸무게가 78킬로인 남성이 있습니다. 이름은 Tomas이고 나이는 37세입니다.

  2. 음식점에 배달 주문이 들어왔습니다.

    주문 접수 번호 : 202011020003
    주문 핸드폰 번호 : 01023450001
    주문 집 주소 : 서울시 강남구 역삼동 111-333
    주문 날짜 : 20201102
    주문 시간 : 130258
    주문 가격 : 35000
    메뉴 번호 : 0003

09. 참조 자료형 변수

참조 자료형

변수의 자료형은 다음과 같이 구분된다.

변수의 자료형 분류

  • 클래스형으로 변수를 선언한다.
  • 기본 자료형은 사용하는 메모리의 크기가 정해져 있지만, 참조 자료형은 클래스에 따라 다르다.
  • 참조 자료형을 사용할 때는 해당 변수에 대해 인스턴스를 생성해야 한다.
    • (단, String 클래스는 예외적으로 생성하지 않고 사용할 수 있다.)

참조 자료형 정의하여 사용하기

  • 학생이 수강한 과목들의 성적을 산출하려 할 때, 학생 클래스 속성에 과목을 모두 넣으면 불합리하다.
  • 학생(Student)과 과목(Subject)에 대한 클래스를 분리하고, 수강한 과목들을 Subject 클래스 타입의 변수로 선언한다.

Student와 Subject 클래스 구성

  • 선언된 Subject 변수는 아직 생성된 인스턴스가 아니므로, Student의 생성자에서 생성하여 사용한다.

Student.java

package ch09;

public class Student {

	int studentID;
	String studentName;

	Subject korea;
	Subject math;

	public Student(int id, String name) {
		studentID = id;
		studentName = name;
    /*
    this.id = id;
    this.name = name;
    */
		korea = new Subject();
		math = new Subject();
	}


	public void setKoreaSubject(String name, int score) {
		korea.subjectName = name;
		korea.score = score;
	}

	public void setMathSubject(String name, int score) {
		math.subjectName = name;
		math.score = score;
	}

	public void showStudentSocre() {
		int total = korea.score + math.score;
		System.out.println(studentName +  " 학생의 총점은 " + total + "점 입니다." );

	}
}

Subject.java

package ch09;

public class Subject {
	String subjectName;
	int score;
	int subjectID;
}

StudentTest.java

package ch09;

public class StudentTest {

	public static void main(String[] args) {

		Student studentLee = new Student(100, "Lee");
		studentLee.setKoreaSubject("국어", 100);
		studentLee.setMathSubject("수학", 95);


		Student studentKim = new Student(101, "Kim");
		studentKim.setKoreaSubject("국어", 80);
		studentKim.setMathSubject("수학", 99);

		studentLee.showStudentSocre();
		studentKim.showStudentSocre();
	}

}

참조 자료형 예제 실행 결과


10. 접근 제어 지시자(access modifier)와 정보 은닉(information hiding)

접근 제어 지시자 (access modifier)

클래스 외부에서 클래스의 멤버 변수, 메서드, 생성자를 사용할 수 있는지 여부를 지정하는 키워드다.

지시자접근 가능 범위
private같은 클래스 내부에서만 접근 가능 (외부 클래스, 상속 관계의 클래스에서도 접근 불가)
(default)같은 패키지 내부에서만 접근 가능 (상속 관계라도 패키지가 다르면 접근 불가)
protected같은 패키지나 상속 관계의 클래스에서 접근 가능, 그 외 외부에서는 접근 불가
public클래스의 외부 어디서나 접근 가능

get() / set() 메서드

  • private으로 선언된 멤버 변수(필드)에 접근·수정할 수 있는 메서드를 public으로 제공한다.
  • get() 메서드만 제공되는 경우 read-only 필드가 된다.
  • 이클립스에서 자동으로 생성할 수 있다.

정보 은닉

  • private으로 제어한 멤버 변수도 public 메서드가 제공되면 접근 가능하다. 다만, 변수가 public으로 공개되었을 때보다 private일 때 각 변수에 대한 제한을 public 메서드에서 제어할 수 있다는 점이 다르다. 사실 정보 은닉이라기보다 정보 보호에 더 가까울 수도 있다.
public void setMonth(int month) {

		if ( month < 1 || month > 12) {
			isValid = false;
		}
		else {
			this.month = month;
		}
	}
  • 객체 지향 프로그램에서 정보 은닉은 외부에서 접근 가능한 최소한의 정보만 오픈함으로써 객체의 오류를 방지하고, 클라이언트 객체가 더 효율적으로 객체를 활용할 수 있도록 해준다.