[자바] 김영한의 실전자바 - 중급 1편 정리(2)

곽동현·2024년 4월 14일
0
post-thumbnail

[Ch3 - String 클래스]

String 클래스 내부 구조

String 클래스 내부로는 사실 char[] 배열로 보관하고 있다.
(📌 자바 9 이후에는 byte[]로 보관한다)

String 클래스는 개발자가 직접 다루기 불편한 char[] 을 내부에 감추고, String 클래스를 사용하는 개발자가 편리하게 문자열을 다룰 수 있도록 다양한 기능을 제공한다.

String 클래스는 참조형이다


        String a = "hello"; //x001
        String b = "java";  //x002

        String result1 = a.concat(b);
        String result2 = a + b;

        System.out.println(result1);	//hellojava
        System.out.println(result2);	//hellojava

String 클래스는 참조형이기 때문에 +연산자는 원래 불가하다. (concat() 과 같은 메서드로만 허용해야함)
하지만 자주쓰이는 문자열의 특성상, + 연산자를 허용해준다.

동일성과 동등성

  • 동일성 : 두 객체가 같은 참조값(인스턴스)을 가리키고 있는지 확인하는 비교법 ( == 연산자 )
  • 동등성 : 두 객체가 다른 인스턴스라도, 논리적으로 같은 객체인지 확인하는 비교법 ( equals() 메서드 )
String str1 = new String("hello");
String str2 = new String("hello");

System.out.println("new String() == 비교 " + (str1 == str2)); // false
System.out.println("new String() equals 비교 " + (str1.equals(str2)));

문자열 리터럴과 문자열 풀

String 클래스는 new로 생성할 때 마다 다른 인스턴스라는 것을 기억한다면, 아래와 같은 코드에 의문이 생길 것이다.

String str3 = "hello";
String str4 = "hello";

System.out.println("리터럴 == 비교 : " + (str3 == str4));    // true (네?????)
System.out.println("리터럴 equals 비교 : " + (str3.equals(str4)));   //true

엥? str3==str3 가 true 라고?
이런 의문이 들었다면, String 클래스의 개념이 잘 잡힌 것이다. 서로 다른 인스턴스로 생성되는 것이 분명한데 왜 true가 나올까?

이때, 문자열 pool이라는 개념이 등장한다.

📌리터럴로 문자열이 생성되면, 같은 문자열을 가진 객체들은 하나의 주솟값을 가리키게 된다!
아래 메모리 주솟값을 한 번 출력해보자.

        String str1 = new String("hello");
        String str2 = new String("hello");

        System.out.println("new String() == 비교 " + (str1 == str2)); // false
        System.out.println("new String() equals 비교 " + (str1.equals(str2)));    //true

        String str3 = "hello";
        String str4 = "hello";

        System.out.println("리터럴 == 비교 : " + (str3 == str4));    // true (네?????)
        System.out.println("리터럴 equals 비교 : " + (str3.equals(str4)));   //true

        System.out.println(System.identityHashCode(str1));  //1989780873
        System.out.println(System.identityHashCode(str2));  //1480010240
        System.out.println(System.identityHashCode(str3));  //81628611
        System.out.println(System.identityHashCode(str4));  //81628611

이와같이 new로 생성했을 때에는, 다른 인스턴스로 메모리에 생성되지만, 리터럴로 생성했을 때에는 문자열 풀에 의해서 같은 인스턴스를 가리키게 된다.

헉 그럼 같은객체를 가리키면 값이 변경되면 어떡해요?

노노! 그런걱정은 하지않아도 된다!
왜? String 클래스는 불변 객체이기 때문이다.
값을 변동하고 싶으면 모두 새로운 객체로 생성해서 반환시킨다.

[Ch4 - 래퍼, Class 클래스]

Wrapper 클래스 특징

  • Null을 가질 수 있다.
  • 불변이다.
  • 값을 비교할 때는 equals()로 비교해야 한다.
  • AutoBoxing - AutoUnboxing 기능을 제공한다.

📌내부 연산 10000번 줄이는 것 보다, 네트워크 호출 1번 줄이는 것이 훨씬 성능이 높아진다.

Class 클래스 - 리플렉션

Class 클래스를 사용하면 클래스의 메타 정보를 기반으로 클래스에 정의된 메서드, 필드, 생성자 등을 조회하고 이들을 통해 객체 인스턴스를 생성하거나 메서드를 호출하는 작업을 할 수 있다. 이런 작업을 리플렉션이라고 한다.
-> 아마 Spring, Mock?에서 많이 쓰이는 것 같다.

profile
실패의 경험들을 채워나가기!

0개의 댓글