본문 바로가기
👨‍💻 2. 웹개발_Back end/2-1 Java

[JAVA] 05-1 참조타입과 참조변수

by 달님🌙 2021. 7. 28.
반응형
참조타입

 

- 기본 타입인 char, int, float 등은 실제 '값'을 변수 안에 저장하지만 참조변수는 주소를 나타낸다.

- 기본타입은 하나의 값만을 담고 있는 반면, 참조변수는 데이터가 여러 개 들어있다.

 예) 클래스(참조변수)는 내부에 속성과 기능 등을 부여하기 위해 데이터가 하나가 아니라 여러 데이터가 모여있음

 

- ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ <-이런 칸 중에 몇 번째 칸은 몇 동을 의미, 그 다음은 몇호를 의미 

- 참조 타입 : 번지 수를 저장 해놓으면 찾아서 쓸 수 있다.

> 참조타입은 이렇게 변수명을 입력하고 온점(.)을 치면 아래 메소드들이 쭉 나온다는 특징이 있다. 

 

 

 

메모리 영역

 

 

메소드 영역 이란 ? 

- 클래스 내의 메소드에 해당하는 바이트 코드와 클래스 변수 등이 저장되는 공간

 

힙 영역 이란 ?

- 객체와 배열이 생성되는 영역

-  여기서 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필에서 참조

- 사용하지 않는 것은 자바가 알아서 쓰레기 수집기를 실행시켜 자동으로 제거함

 

 스택 영역 이란 ? 

- 메소드를 호출할 때마다 프레임을 추가, 메소드 종료시 해당 프레임 제거

- 변수는 선언된 블록 안에서만 스택에 존재하고 벗어나면 스택에서 제거됨

 

 

 

 

return문의 위치

 

//return이 맨아래 나옴
public static void main(String[] args) {
  System.out.println("a");
  System.out.println("b");
  return;
}

//return이 중간에 나옴
public static void main(String[] args) {
  System.out.println("a");
  return;
  System.out.println("b"); // Unreachable code 에러 발생
}

> unrechable code : 실행을 못할때 생기는 에러

 

NullPointerException 예외 발생

 

String str1 = "";
String str2 = null;
System.out.println(str1 == str2);

A a1;
a1 = new A(); // 이 구조 중요함. new ~ 로 쓰는 거 자주 까먹으니 주의할 것

System.out.println(a1.a);
System.out.println(a1.b); 
System.out.println("프로그램 종료");
	}
}
class A {
	int a = 1;
	int b = 2;
}
false
1
2
프로그램 종료

 

 

String 타입

 

** String 타입 예제

System.out.println("a");
System.out.println("b"); 
// return; -> Unreachable code 에러 발생

System.out.println("Hello");
System.out.println("Hello".toString()); //같은 결과 출력
// 문자열에는 주소값이 들어있음
// System.out.println(0x3BCD.toString()); 이런 의미임

 

**  String 타입 특징

String str1 = "java";
String str2 = "java";

System.out.println(str1 == str2); // true -> 같은 주소에 있음을 알 수 있음
System.out.println(str1.hashCode()); // 3254818
System.out.println(str2.hashCode()); // 3254818 -> 같은 값 나옴

- String 타입은 4byte로 정해져있다. -> 긴 문자열(값)이 저장되기에는 부족하다 

- 그래서 주소 값만 담기는 것이다.

- 힙영역에 "java" 가 생성된다.  string객체의 멤버가 됨

- 그 "java" 라고 저장된 "위치(주소)"를 스택 영역에 저장하는 것이다.

 

- str2도 "java"라는 문자열로 대입하면 str1과 같은 문자열인데 굳이 또 공간을 내주어서 새로 만들까?

- No. 100개를 선언한다고 100개 다 만들어낸다면 그건 메모리 낭비이다.

- str1의 주소를 참조해서 꺼내오라고한다. -> 똑같은 주소를 리턴해주는것


String str3 = new String("java");
String str4 = new String("java");

System.out.println(str3 == str4); //false
System.out.println(str2.contentEquals(str4)); //true
System.out.println(str2.contentEquals(str4)); //true
System.out.println(str2 == str3); //false

System.out.println(System.identityHashCode(str1)); // 366712642
System.out.println(System.identityHashCode(str2)); // 366712642
System.out.println(System.identityHashCode(str3)); // 1829164700
System.out.println(System.identityHashCode(str4)); // 2018699554

- 원래 만들어놓은 주소말고 새로 참조하고 싶을 때는 new를 이용한다.

- 그렇다고 new 를 사용하는 방법만 쓰는건 단점이 있다. 힙영역에 메모리가 계속 채워지므로 낭비가 심해진다.

- str3와 str4는 new를 이용하여 새롭게 참조한 것이므로 주소 값이 달라 str3 != str4 이다.

- 그러나 주소는 달라도 그 내용은 같음 ->  contentEquals 하면 true가 나온다

  비유) 101호에도 102호에도 모두 집집마다 쇼파가 있다(내용이 같음) 하지만 주소는 다르다.

 

** String 타입 예제 2

System.out.println("\nString을 그냥 변수타입으로 사용했을때");
String strVar1 = "신민철";
String strVar2 = "신민철";

if(strVar1 == strVar2) {
	System.out.println("strVar1과 strVar2는 참조가 같음");
} else {
	System.out.println("strVar1과 strVar2는 참조가 다름");
}

if(strVar1.equals(strVar2)) {
	System.out.println("strVar1과 strVar2는 문자열이 같음");
}

System.out.println("\nString을 New 방법으로 사용했을때");
String strVar3 = new String("신민철");
String strVar4 = new String("신민철");

if(strVar3 == strVar4) {
	System.out.println("strVar3과 strVar4는 참조가 같음");
} else {
	System.out.println("strVar1과 strVar2는 참조가 다름");
}

if(strVar3.equals(strVar4)) {
	System.out.println("strVar3과 strVar4는 문자열이 같음");
}

 

 

반응형

댓글