자바 기타
포스트
취소

자바 기타

String 변수의 생성 방식 두 가지

생성자 매개변수를 통한 생성 String str = new String(args)

  • 인스턴스 생성이므로 독립된 heap 영역에 존재하여 동등 연산자로 비교 불가
  • 문자열이 가지는 불변성 논리에 모순이 생김

생성자를 호출하지 않는 생성 String str = "args"

  • heap 영역의 문자열 상수 풀에 저장됨
  • 동등 연산자로 비교할 수 있음
  • 참조를 잃으면 GC에 의해 제거 된다

메모리를 효율적으로 사용하기 위해 인스턴스 생성을 피하자

명칭 규약

  • 상수의 이름은 모두 대문자로
  • 기능을 위한 인터페이스의 이름은 형용사로

자바에서의 API

  • 자바 시스템을 제어하기 위해 자바에서 제공하는 명령어들을 의미
  • SE(JDK)를 설치하면 기본 API를 제공
  • 패키지 내의 클래스들도 자바에서 제공하는 API 중 하나

clone

직접 작성한 클래스에 clone 메소드를 정의하고 싶다면 Cloneable 인터페이스를 상속해야 한다 이 메소드는 인스턴스의 복사본을 만들어 참조 값을 반환한다(얕은 복사) 깊은 복사를 위핸 clone 메소드를 오버라이딩하고 인스턴스 내부의 참조 변수에까지 clone 메소드를 사용해준다

clone 오버라이딩 과정

1
2
3
메소드 내부에 인스턴스 복사본 생성
필드 복사
인스턴스 반환

Comparable & Comparator

두 개 모두 인터페이스이므로 추상 메소드의 실체화가 필요하며, 리터럴에 포함되지 않는 자료형인 객체를 비교할 수 있는 수단이다. Comparable : compareTo (T o) : 자신과 매개 변수 객체를 비교 : 익명 구현 객체 의미없음. : 구현 클래스 오버라이딩 Comparator : compare(T o1, T o2) : 두 매개 변수 객체를 비교 : main문에 람다식 정의 가능 Comparable은 lang 패키지에 존재하기에 import 해줄 필요가 없지만 Comparator는 util 패키지에 존재한다. Comparable 은 구현 클래스에 직접 오버라이딩. Comparator 는 람다식을 이용한 익명 구현 객체 생성 후 정렬 메소드의 인자로 전달. 이러한 특성으로 Comparator는 다중 생성 가능하지만 Comparable의 경우 단 하나의 방식 밖에 못 쓴다. flow를 주의하여 사용하자.

시각과 날짜 관련 코드의 작성

1
2
3
4
5
6
7
8
9
10
11
java.util.Date(자바0) 구식 SimpleDateFormat 클래스로 형식 변환 
java.util.Calendar(자바1) 구식
(자바8) + DateTimeFormatter(Instant는 포맷 적용이 까다롭다)
java.time.Instant  1970 - 01 - 01 00:00:00 부터 현재까지 흐르는 시간 중 특정 지점을 인스턴스로 생성 (UTC 기준 시간)
java.time.Duration 소요 시간을 계산하는 데 이용
java.time.LocalDate 시각 정보가 생략된 날짜 정보를 표현
java.time.LocalTime 시각 정보를 표현
java.time.period 날짜 기간을 계산하는 데 이용
java.time.LocalDateTime 
java.time.ZoneId 협정 세계시에 따른 시각 계산을 위해 지역 지정
java.time.ZonedDateTime 지역에 따른 시각을 표현할 수 있음 
  • 대부분 메소드를 사용하면 인스턴스를 수정하는 게 아니라 수정한 정보를 토대로 새로운 인스턴스를 반환한다
  • 한국의 시간대는 UTC+9 : 협정 세계시보다 9시간이 빠름을 의미한다
  • Local, Zone의 기본 값은 사용자 컴퓨터에 맞춰져있다 [참고] https://jaimemin.tistory.com/1537

해시코드

  • 해시 코드는 알고리즘과 데이터 구조가 객체를 구획에 넣을 수 있도록 한다
  • 이 간단한 시스템을 사용하면 분류되지 않은 서랍에서 검색하는 것보다 훨씬 빠르게 유형을 찾을 수 있다 계약 동일한 객체는 실행 중인 프로세스 내에서 동일한 해시코드를 가져야 한다 아래와 같은 일반적인 오해를 의미하진 않는다.
  • 동일하지 않은 객체는 다른 해시 코드를 가져야 한다 : false
  • 동일한 해시코드를 가진 객체는 동일하다 : false
  • 계약에서는 동일하지 않은 객체가 동일한 해시코드를 공유하는 것을 허용한다
  • 구별 가능한 객체의 수가 해시코드의 수(4byte)보다 많기 때문에 명백하다 재정의
  • 이로써 equals를 구현할 때마다 hashcode도 재정의해야함을 알 수 있다 그렇지 않다면 깨진 물건으로 끝날 것이다.
  • equals 메소드를 재정의하여 일부 객체를 다른 객체와 동일하게 선언하지만 원래 해시코드는 모든 객체를 다른 것으로 취급한다 따라서 해시코드가 다른 동일한 객체를 갖게 된다
  • 특정할 수 있는 필드 값에 대한 연산을 이용하여 재정의 충돌
  • 두 개의 서로 다른 객체가 동일한 해시코드를 가질 때, 이를 충돌이라 한다
  • 충돌은 중요하지 않으며, 단일 버킷에 둘 이상의 객체가 있음을 의미한다
  • 해시코드를 객체에 대한 고유 핸들로 착각하면, 예를 들어 Map의 Key로 사용할 때, 때때로 잘못된 결과를 얻게 된다 충돌은 드물지만 피할 수 없기 때문이다 (System 클래스의 hashcode 메소드를 사용하여 얻은 정수를 16진수로 표현한 게 Object 클래스의 메소드)

etc

  • 지역 변수는 스코프를 벗어나면 메모리에서 소멸된다.
  • 정보 은닉 : 자바에서 말하는 ‘정보’는 클래스의 ‘인스턴스 변수’를 의미한다 따라서 정보를 은닉한다는 것은 위 변수를 숨긴다는 뜻 (private 선언)
  • 캡슐화 : 하나의 목적을 이루기 위해 관련된 사항을 하나의 클래스에 담음
  • 참조를 목적으로 정적 멤버를 선언할 때, final 선언에 대한 여부를 고민
  • main 메소드의 호출이 이뤄지는 영역은 클래스 외부. 당연히 public 선언해야함
  • 콘솔 : 컴퓨터를 대상으로 데이터 입출력을 담당하는 장치를 총칭
  • toString, equals, hashcode 오버라이딩 권장
  • 어노테이션은 컴파일러에게 메시지를 전달하는 목적의 메모
  • 자바5부터 오버라이딩 과정에서 반환 타입의 수정을 허용한다. 단 클래스 이름과 관련한 조건이 있다
  • 다른 프로젝트에 있는 클래스는 ‘jar’ 추출 후 라이브러리로 추가하자
  • 값은 웬만하면 변수에 대입하자. 협업에 유리하다 소스코드에 데이터를 직접 기입하면 유지보수에 애로사항이 생길 것이다
  • 가변 인자를 전달하면 컴파일러가 배열로 해석한다
  • 터미널 컴파일시 -Xlint(enable recommended warnings)로 경고 확인 가능
  • 버퍼란 동작 속도가 크게 다른 두 장치 사이에 접속되어 속도 차를 조정하기 위하여 이용되는 일시적인 저장 장치
  • 메소드는 단 한가지의 기능만 수행하도록 작성하자
  • 도트 연산자는 한 줄에 하나만 쓰도록 하자
  • 인터페이스와 컴포지션으로 기능을 분리하여 OCP 원칙을 지키자
  • 컴포지션에 매몰되면 상속의 이점을 놓친다
  • 메소드 매개변수와 반환 타입은 최대한 인터페이스로 정의하자
  • instanceof 를 이용한 분기문보단 다형성을 이용하자
  • 불변식은 Thread-safe를 보증한다는 말도 된다
  • 클라이언트로부터 데이터를 보호하기 위해 방어적 복사를 지향하자
  • 동등성을 판별하는 필드로 최적화된 건 Primary Key
  • 재귀보단 반복문을 사용하자. 순환 참조(Stack overflow) 위험이 있다
  • Optional과 Collection Stream은 가독성을 챙기기 좋은 수단
  • 상태를 가지는 객체를 정의했다면 제대로 된 역할을 하도록 구현하자 객체가 로직을 구현하도록 해야하며 데이터를 꺼내지 않고 객체에 메시지를 보내 일을 하도록 리팩토링해야 한다
  • 비즈니스 로직은 DB가 아닌 앱에 넣자. 일반적으로 app 서버 리소스가 DB 서버 리소스보다 확장하기 훨씬 더 쉽기 때문에 대용량 데이터 중 소수만 가져오는 로직이 아닌 이상 DB 리소스 사용을 최소화하자
  • 인스턴스 필드의 개수가 많아 초기화할 매개 변수의 양이 늘어났을 때 빌더 패턴을 고려하자. 계층 구조에서 활용할 수 있으며 현재 필드가 적더라도 늘어날 가능성이 있다면 비용은 뒤로하고 고려해보자
  • 향상된 for문은 iterable 구현 클래스와 일반 배열만 사용 가능하다 for(Iterator<String> str = strings.iterator(); str.hasNext()) 로 표현 가능 또는 선언은 외부에 하고 while 문에 hasNext 를 등록할 시 동일한 표현 향상된 for문 내부에서 해당 컬렉션의 수정은 자제하자

Q

  • Comparator 인터페이스 구현 클래스는 꼭 따로 작성해줘야 되나?
  • 병렬 스트림 활용 사례
  • I/O 스트림 모델
  • I/O 스트림은 반드시 1바이트를 int형으로 전환하는 과정이 필요한가
  • JVM이 문자를 메모리에 저장할 때 UTF-16 방식을 사용하는가
  • JVM의 인코딩 방식을 직접 설정할 수 있는가
  • 요청이 올 때마다 스레드가 생성되는데 서버에는 얼마나 많은 코어가 존재하는가
  • 컴포지션과 상속의 장단점
  • 빌더 패턴에서 말하는 계층 구조 활용
  • printf 와 format 메소드 관계
  • Enum 상수의 수가 많아질 때
  • 익명 자식 객체의 필요성
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.