참조 자료형 심화

김현우·2024년 5월 15일
0

java

목록 보기
7/12
post-thumbnail

참조 자료형인 이유?

참조자료형의 저장 방식과 연관이 되어있다.

c++에서 new는 동적할당을 받기위한 명령어이다.
자바에서도 마찬가지로 new를 통해 생성되는 자료형은 사실 heap영역에 생성이 된다.

힙영역 어딘가에 해당 자료형이 생성되고 주소를 가져와 스택에서 "참조(referrence)"하기 때문에 참조 자료형이다.

저장방식

참조 자료형을 생성할때 우리는
String str = new String(); 꼴로 생성한다.

이때 힙영역에 String 자료형이 생성된 이후 주소값을 str에게 저장시킨다.
str은 스택영역에 존재하며 동적할당된 String의 주소값을 가지고 있다.

그렇다면 String str;만 진행하고 new String();을 하지않았을때 str의 값이 null인 이유가 나온다.

어떤 주소도 저장이 되어있지 않기에 참조할 데이터가 없다는 의미로 null이라 표현된다.

Wrapper(포장) Class

int,char등등 이런 기본타입을 "객체"로 사용하기 위해서 
wrapper class를 사용한다.

java.lang에 포함되어 있기에 추가 import없이 사용이 가능하다.

종류

기본 자료형 - byte, short, int, long, float, double, boolean,char
wrapper class = Byte,Short, Integer, Long, Float, Double, Boolean, Character

int,char를 제외하면 앞글자만 대문자이다.

사용법

다른 객체와 같이 똑같이 클래스를 선언한다.

Integer i1 = new Integer(5);
초기값을 넣어줘야하는데 신기한건 String을 넣어도 int로 자동 변환해준다.

또는 valueOf라는 static 매소드를 사용할수도 있다.

Integer i2 = Integer.valueOf(5);

내부 값 변경

String은 불변하는 자료형이였다.
String을 바꾸고 싶다면 내부 값을 바꾸는것이 아니라 
변경한 새로운 문자열 생성후 그 주소를 갈아끼우는 것이였다.

class practice{
    public static void main(String[] args) {
        String s1=new String("hi");
        System.out.println(s1.hashCode());

        s1="ih";
        System.out.println(s1.hashCode());
    }
}

이렇게 실행을 하였을때 결과를 보면

이처럼 해시코드가 다르다는 것을 알수있다.

즉, 기본 자료형처럼 내부 값이 바뀌는게 아니라 새로운 참조자료형이 갈아끼워진 것이다.

new vs valueOf

두개의 차이점은 무엇일까?

new는 항상 새로운 객체를 만들어준다.
만약에

Integer i1 = new Integer(1);
Integer i2 = new Integer(1);

로 둘다 같은 값을 할당 시키더라도 객체를 2개 만든후 각각 할당해준다.
따라서 두 객체를 비교해보면 서로 다르다고 나온다.

class practice{
    public static void main(String[] args) {
        Integer i1=new Integer(5);
        Integer i2=new Integer(5);
        
        System.out.println(i1==i2);
        
    }
}

valueOf는 같은 값을 사용하면 같은 객체를 할당해준다.

Integer i3 =Integer.valueOf(5);
Integer i4 =Integer.valueOf(5);

와 같이 있다면 두 객체는 같다.

class practice{
    public static void main(String[] args) {
        
        Integer i3=Integer.valueOf(5);
        Integer i4=Integer.valueOf(5);


       System.out.println(i3==i4);
        
    }
}

따라서 valueOf를 사용하는것이 권장된다.

단 일정범위 -127~128까지만 그렇고 범위를 벗어나면 new와 동일하다.

class practice{
    public static void main(String[] args) {
                Integer i5=Integer.valueOf(150);
        Integer i6=Integer.valueOf(150);

        System.out.println(i5==i6);

    }
}

*** 추가

wrapper 클래스는 그냥 =을 사용하기도 한다.
이때 내부적으로는 valueOf를 사용하는 것과 동일한 결과가 나온다.

Integer i7=1;
Integer i8=1;

System.out.println(i7==i8); 비교시 true가 나온다.
profile
학생

0개의 댓글