자바 기본(2)
14 Oct 2019 | JavaJAVA 프로그래밍 면접 이렇게 준비한다 - 한빛미디어를 학습하며 공부한 것을 정리한 내용입니다.
소개
- 메서드와 변수에 사용되는 static 키워드의 역활은 무엇인가?
- String과 interning
- 메서드와 변수에 사용되는 static 키워드의 역활은 무엇인가?
Class Person{
// 정적 변수
public static List<String> nationality = new ArrayList();
// 정적 메셔드
public static void staticMethod(){
...
}
}
static 키워드가 붙은 변수는 정적 변수, static 키워드가 붙은 메서드는 정적 메서드라 한다.
- 정적 변수와 정적 메서드는 클래스가 로딩될때 static 영역에 할당되어 프로그램 종료시까지 객체 생성없이 접근이 가능하다.
- 클래스.정적변수, 클래스.정적메서드() 로 접근하고 사용한다.
- ex) Person.nationality, Person.staticMethod()
- 프로그램 종료 시까지 static 영역에 존재하므로 정적 변수와 정적 메서드를 남발한다면 메모리를 낭비시킬 수 있다.
정적 변수와 정적 메서드는 클래스 내부에 정의하지만 인스턴스에는 속하지 않는다.
-
정적 변수를 사용하는 이유 모든 인스턴스에서 공통으로 사용하는 변수를 정적 변수로 선언하고 사용한다면 객체 생성시마다 중복된 값이 생성되어 발생하는 메모리 낭비를 막을 수 있다.
-
정적 메서드를 사용하는 이유 정적 변수를 사용하려면 메서드를 정적 메서드로 선언해야 하며, 자주 사용하는 Util 성격의 클래스들을 정적 메서드로 선언하면 인스턴스화 없이 편하게 사용가능 하다.
Class Person{
// 정적 변수가 아니라면 Person 객체가 인스턴스화 될때마다 nationality가 생성되어 메모리 낭비가 발생할 겻이다.
public List<String> nationality = new ArrayList();
// 정적 메셔드
public static void staticMethod(){
...
}
}
- String과 interning
String 객체를 생성하는 방법은 2가지가 있다.
-
리터럴을 이용하는 방식.
-
new 연산자를 이용하는 방식.
두 가지 방법의 차이는 무엇일까?
리터럴을 이용하여 String 객체를 생성하면 string constant pool이라는
Heap 영역 중에 특별한 곳에 저장되고, new 연산자를 이용하여 객체를 생성하면 Heap 영역에 생성된다.
’==’ 연산자와 ‘equals()’ 메서드를 이용하여 구체적으로 살펴보자.
’==’ 연산자는 물리적인 메모리 주소가 같은 지 판별하는 연산자이고, String 클래스의 ‘equals()’ 메서드는 문자열이 같은 지 판별하는 메서드이다.
Class Main{
public static void main(String[] args) {
String literal = "Cat"; // 리터럴을 이용한 방식
String obj = new String("Cat"); // new 연산자를 이용한 방식
System.out.println(literal == obj); //false
System.out.println(literal.equals(obj)); //true
}
}
-
결과 string constant pool에 생성된 literal과 일반 객체처럼 Heap 영역에 생성된 obj의 주소 값은 다르므로 == 연산 결과는 false일 수 밖에 없으며, equals()의 결과는 true이다.
-
intern() 메서드 String을 literal로 선언할 경우 내부적으로 intern() 메서드를 호출하게 된다. intern() 메서드는 주어진 문자열이 string constant pool에 존재하는 지 확인하고 존재한다면 그 주소값을 반환하고 없다면 string constant pool에 넣고 새로운 주소값을 반환하게 된다.
Class Main{
public static void main(String[] args) {
String literal = "String"; // 리터럴을 이용한 방식
String obj = new String("String"); // new 연산자를 이용한 방식
String intern = obj.intern();
System.out.println(literal == obj); //false
System.out.println(literal == intern); //true
System.out.println(literal.equals(obj)); //true
System.out.println(literal.equals(intern)); //true
System.out.println(obj == intern); //false
System.out.println(obj.equals(intern)); //true
}
}
ref. https://www.journaldev.com/797/what-is-java-string-pool
ref.https://medium.com/@joongwon/string-%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC%EC%97%90-%EB%8C%80%ED%95%9C-%EA%B3%A0%EC%B0%B0-57af94cbb6bc