자바 기본(2)

|

JAVA 프로그래밍 면접 이렇게 준비한다 - 한빛미디어를 학습하며 공부한 것을 정리한 내용입니다.

소개

  1. 메서드와 변수에 사용되는 static 키워드의 역활은 무엇인가?
  2. String과 interning

  1. 메서드와 변수에 사용되는 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(){
   ...
  }

}

  1. String과 interning

String 객체를 생성하는 방법은 2가지가 있다.

  1. 리터럴을 이용하는 방식.

  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