본문 바로가기

Java

참조타입

참조타입

1. 데이터 타입 분류

데이터 타입은 기본 타입(primitive type)과 참조 타입(reference type)이 있다.

기본 타입에는 byte, char, short, int, long, float, double, boolean이 있고, 참조 타입에는 배열타입, 열거타입, 클래스, 인터페이스가 있다.

둘의 차이는 메모리에 어떻게 저장되냐인데 기본 타입은 메모리에 실제 값 자체가 저장되고, 참조 타입의 경우에는 메모리에 주소 값을 저장한 후 주소 값으로 객체를 참조한다.

2. 메모리 사용 영역

java.exe 실행 시 JVM이 메모리 공간을 할당 받는데 메모리를 다음 그림 처럼 구분해서 사용한다.

메소드 영억, 힙 영역, 스택 영역

메소드 영역

JVN 실행 시 생성 되고, 모든 스레드가 공유하는 영역이다. 클래스(~.class)들을 읽어 클래스별로 영역을 만들어서 런타임 상수풀, 필드, 메소드, 생성자 코드 등으로 분류해서 저장한다.

힙 영역

객체와 배열이 생성되는 영역이다. 각 객체나 배열을 참조하고 애 없으면 가비지컬렉터가 제거한다. 메모리를 아낄 수 있음

스택 영역

스레드 하나 마다 할당된다. 쉽게 말해 한 작업에 하나의 스택 영역을 할당한다고 보면 된다.

JVM 스택은 메소드를 호출할 때 마다 프레임을 추가하고, 종료하는 동작을 수행한다.

1. char v1 = 'A';

2. if(v1 =='A'){
	int v2 = 100;
	double v3 = 3.14;
}

3. boolean v4 =true;

만약 참조타입이라면? 객체는 heap영역에, stack에는 주소가 담긴다.

3. 참조 변수의 ==, ≠ 연산

A == B 는 true

A == C 는 false.

==, ≠은 주소 값을 비교하기 때문이다.

4. null과 NullPointerException

null은 힙 영역의 객체를 참조하고 있지 않다는 뜻이다.

이 그림에서 변수 b와 c는 null을 가지고 있다고 볼 수 있다.

만약 b나 c를 값이 할당되지 않은 채로 쓰려고 한다면? NullPointerException이 발생한다.

a == null // false
b == null // true
c == null // true

5. String 타입

자바에서 문자열은 String 변수에 저장한다. 스택 영역에 기본 값으로 저장하는 것이 아니라 힙 영역에 객체로 저장되는 것이다.

String name = "찬찬찬";
String hobby = "코딩";

이런 식으로 선언하면 메모리 영역에는 다음과 같이 생성된다.

문자열 리터럴이 동일하다면 String 객체를 공유하도록 되어있다. 메모리를 아끼기 위해

String name1 = "찬찬찬";
String name2 = "찬찬찬";

근데 String 객체를 공유하고 싶지 않다면? new 연산자를 사용해서 객체를 생성해주면 된다

String name1 = new String("찬찬찬");
String name2 = new String("찬찬찬");

여기서 name1과 name2가 같은지 확인하고 싶다면?

배운대로 ==을 쓰면 false가 나온다. 왜냐하면 주소 값이 다르니까.

그래서 String 객체에서 equals() 메소드를 따로 만들어뒀다.

name1 == name2 // false;
name1.equals(name2) // true;

6. 배열 타입

변수엔 데이터 한 개만 저장할 수 있다.

여러 개 저장하고 싶을 때? 데이터 타입이 같으면 여러개를 저장할 수 있다.

index는 번호표 같은 개념이다. index는 0부터 시작한다.

선언은 타입[ ] 변수; 타입 변수[ ] 두 가지로 할 수 있다.

int[] intArray = {15, 20, 35, 45, 55};
String[] strArray;
int intArray[] = {15, 20, 35, 45, 55}
String strArray[];

데이터 값 정해지지 않았을 경우

값의 목록을 갖고 있진 않지만, 나중에 값들을 저장할 배열을 미리 만들어두고 싶다면? new 연산자를 사용해서 배열 객체를 생성시킬 수 있다.

int[] intArray = new int[5];
//index가 5개인 배열이 생성되어있음.

new 연산자로 배열을 처음 생성할 경우 배열 안에 든 값은 모두 0으로 초기화 되어있다.

System.out.println(intArray[0]); //0
System.out.println(intArray[1]); //0
System.out.println(intArray[2]); //0
System.out.println(intArray[3]); //0

문자열의 경우 null로 초기화 된다.

boolean타입의 경우 false

double타입의 경우 0.0

+배열에 클래스나 인터페이스도 담을 수 있다.

배열 길이

배열 객체의 length 필드를 읽으면 배열의 길이를 알 수 있다.

int score[] = {30, 40, 50};
int sum = 0;
for(int i = 0 ; i<score.length ; i++){
	sum += score[i];
}
System.out.println("총합 : " + sum);

main() 메서드

public static void main(String[] args){ ... }

"java 클래스"로 프로그램을 실행 → JVM이 길이가 0인 String 배열을 생성하고 → main()메소드를 호출할 때 매개값으로 전달한다.

String[] args = {};

public static void main(String[] args){ ... }

다차원 배열

배열 안의 배열

int[][] scores = new int[2][3]

int[][] scores ={{10,20,30},{11,21,31}};

배열은 다시 주소를 참조한다.

배열복사

for문으로

int[] oldArray = { 1, 2, 3 }
int[] newArray = new int[3];

newArray = oldArray // 주소 값이 복사.

for(int i = 0 ; i <oldArray.length; i++){
	newArray[i] = oldArray[i];
}

System.arraycopy() 메서드

System.arraycopy(oldArray, 0, newArray, 0, oldArray.length);
System.arraycopy(oldArray, 시작인덱스, newArray, 시작인덱스, 복사할 갯수);

7. 열거 타입

데이터 중 몇 가지로 한정된 값만 갖는 경우가 있다.

요일은 월,화,수,목,금,토,일이라는 값만 갖고 계절은 봄, 여름, 가을, 겨울만 갖는다.

한정 된 데이터 값만 갖는 타입을 열거 타입(enumeration type)이라 한다.

선언

열거 타입은 사용자가 지정해줘야한다. 그래서 파일을 따로 만든다.

[File- New - Enum]

예) Week.java

public enum Week{
	MONDAY,
	TUESDAY,
	WEDNESDAY,
	THURSDAY,
	FRIDAY,
	SATURDAY,
	SUNDAY
}

public enum 키워드는 열거 타입을 선언하기 위한 키워드! 반드시 소문자로 작성해야한다.

MONDAY, TUESDAY → 열거상수라 부른다.

만약 두 단어 이상이 연결되면 로 연결하는 것이 관례다. LOGINSUCCESS, LOGIN_FAILED

사용

Week today;
Week tomorrow = Week.MONDAY;

날짜 및 요일, 시간

+자바는 컴퓨터의 날짜 및 요일, 시간을 프로그램에서 사용할 수 있도록 클래스를 제공한다.

Date(사용 권장x), Calendar, LocalDateTime(자바 8부터 지원)

Calendar now = Calendar.getInstance();
Calendar 클래스는 추상클래스이기 때문에 직접 객체를 생성할 수 없고, 메서드를 통해서 완전히 구현된 클래스의 인스턴스를 얻어와야 함

int year = now.get(Calendar.YEAR); //년
int month = now.get(Calendar.MONTH)+1; //월(1-12)
int day = now.get(Calendar.DAY_OF_MONTH); //일
int hour = now.get(Calendar.MONTH); //시간

열거 객체의 메소드

모든 열거 타입은 컴파일 시에 Enum 클래스를 상속하기 때문에 Enum 클래스가 가지고 있는 데이터 및 메소드들을 쓸 수 있다.

name()메소드

열거 객체가 가지고 있는 문자열 리턴

Week today = Week.MONDAY;
String name = today.name(); // 문자열 "MONDAY" 리턴. String name에 "MONDAY"가 담김

ordinal()메소드

전체 열거 객체 중 몇 번째 열거 객체인가? 0부터 시작

Week today = Week.SUNDAY;
int ordinal = today.ordinal(); // > 6.

compareTo() 메소드

비교해보자. 순번 빠르면 양수, 순번 늦으면 음수 반환

Week day1 = Week.MONDAY;
Week day2 = Week.WEDNESDAY;
int result1 = day1.compareTo(day2); //MONDAY 번호는 0 , WEDNESDAY는 2. 0-2는? -2
int result2 = day2.compareTo(day1); //MONDAY 번호는 0 , WEDNESDAY는 2. 2-0는? 2

valueOf() 메소드

(안에 문자열)이랑 똑같은 문자열 갖고 있나? 그럼 안에 있는 열거 객체로 줘.

Week weekDay = Week.valueOf("SATURDAY");
//외부에서 문자열 받아서 열거 객체로 변환할 때 유용함

values() 메소드

열거 객체 모두를 배열로 반환

Week[] days = Week.values();
//days -> [MONDAY, TUESDAY, ... , SUNDAY]

  • 예제1

    자바스크립트 점수 90, 70, 55를 배열에 담고, 총합과 평균을 출력하세요.

반응형

'Java' 카테고리의 다른 글

상속 : final 클래스와 final 메소드  (0) 2021.03.07
상속 : 메소드 재정의(오버라이딩)  (0) 2021.03.07
상속 : 상속의 개념  (0) 2021.03.07
변수와 타입  (0) 2021.02.08
동일성과 동등성(==, equals())  (0) 2021.01.10