리터럴을 사용하면 string constant pool 이라는 영역에 존재하게 되고 new 를 통해 String 을 생성하면 Heap 영역에 존재하게 된다.
String 을 리터럴로 선언할 경우 내부적으로 String 의 intern() 메서드가 호출된다.
intern() 메서드는 주어진 문자열이 string constant pool 에 존재하는지 검색하고 있다면 그 주소값을 반환하고, 없다면 string constant pool 에 넣고 새로운 주소값을 반환한다.
== : 두개의 주소값을 비교
equals() : 두개의 값 자체를 비교
제네릭을 지원하기 전에는 컬렉션에서 객체를 꺼낼 때 마다 형변환을 해줘야했다.
제네릭을 사용하면 컬렉션이 담을 수 있는 타입을 컴파일러에 알려줘서 컴파일과정의 오류를 미리 예방할 수 있다.