제네릭을 사용하기 시작하면 수많은 컴파일러 경고를 보게 될 것입니다. (비검사 형변환 경고, 비검사 메서드 호출 경고, 비검사 매개변수화 가변인수 타입 경고, 비검사 경고 등) 제네릭에 익숙해질수록 마주치는 경고 수는 줄겠지만 새로 작성한 코드가 한 번에 깨끗하게 컴파일되리라 기대하지는 말아야 합니다. 대부분의 비검사 경고는 쉽게 제거할 수 있습니다. 코드를 다음처럼 잘못 작성했다고 해봅시다. Set exaltation = new HashSet(); 그러면 컴파일러는 무엇이 잘못됐는지 친절히 설명해줄 것입니다. (javac 명령줄 인수에 -Xlint:uncheck 옵션을 추가해야 합니다.) Venery.java:4: warning: [unchecked] unchecked conversion Set exa..
클래스와 인터페이스 선언에 타입 매개변수가 쓰이면 이를 제네릭 클래스 혹은 제네릭 인터페이스라 합니다. 예컨대 List 인터페이스는 원소의 타입을 나타내는 타입 매개변수 E를 받습니다. 그래서 이 인터페이스의 완전한 이름은 List지만 짧게 그냥 List라고도 자주 씁니다. 제네릭 클래스와 제네릭 인터페이스를 통틀어 제네릭 타입이라 합니다. 각각의 제네릭 타입은 일련의 매개변수화 타입을 정의합니다. 먼저 클래스(인터페이스) 이름이 나오고, 이어서 꺾쇠괄호 안에 실제 타입 매개변수들을 나열합니다. 예컨대 List은 원소의 타입이 String인 리스트를 뜻하는 매개변수화 타입입니다. 여기서 String이 정규(formal) 타입 매개변수 E에 해당하는 실제(actual) 타입 매개변수입니다. 마지막으로, 제..
소스 파일 하나에 톱레벨 클래스를 여러 개 선언하더라도 자바 컴파일러는 불평하지 않습니다. 하지만 아무런 득이 없을 뿐더러 심각한 위험을 감수해야 하는 행위입니다. 이렇게 하면 한 클래스를 여러 가지로 정의할 수 있으며, 그 중 어느 것을 사용할지는 어느 소스 파일을 먼저 컴파일하느냐에 따라 달라지기 때문입니다. 구체적인 예를 봅시다. 다음 소스 파일은 Main 클래스 하나를 담고 있고, Main 클래스는 다른 톱레벨 클래스 2개를 참조합니다. public class Main { public static void main(Stirng[] args) { System.out.println(Utensil.NAME + Dessert.NAME); } } 집기(Utensil)와 디저트(Dessert) 클래스가 Ut..
중첩 클래스란 다른 클래스 안에 정의된 클래스를 말합니다. 중첩 클래스는 자신을 감싼 바깥 클래스에만 쓰여야 하며, 그 외의 쓰임새가 있다면 톱레벨 클래스로 만들어야 합니다. 중첩 클래스의 종류 중첩 클래스의 종류는 다음과 같습니다. 정적 멤버 클래스 (비정적) 멤버 클래스 익명 클래스 지역 클래스 이렇게 총 네 가지입니다. 이 중 첫 번째, 정적 멤버 클래스를 제외한 나머지는 내부 클래스에 해당합니다. 이번 아이템에서는 각각의 중첩 클래스를 언제 그리고 왜 사용해야 하는지 이야기합니다. 정적 멤버 클래스 먼저 가장 간단한 정적 멤버 클래스를 알아봅시다. 정적 멤버 클래스는 다른 클래스 안에 선언되고, 바깥 클래스의 private 멤버에도 접근할 수 있다는 점만 제외하고는 일반 클래스와 똑같습니다. 정적..
두 가지 이상의 의미를 표현할 수 있으며, 그 중 현재 표현하는 의미를 태그 값으로 알려주는 클래스를 본 적이 있을 것입니다. 다음 코드는 원과 사각형을 표현할 수 있는 클래스입니다. class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double width; // 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다. double radius; // 원용 생성자 Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // 사각형용..
인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 합니다. 달리 말해, 클래스가 어떤 인터페이스를 구현한다는 것은 자신의 인스턴스로 무엇을 할 수 있는지를 클라이언트에 얘기해주는 것입니다. 인터페이스는 오직 이 용도로만 사용해야 합니다. 이 지침에 맞지 않는 예로 소위 상수 인터페이스라는 것이 있습니다. 상수 인터페이스란 메서드 없이, 상수를 뜻하는 static final 필드로만 가득 찬 인터페이스를 말합니다. 그리고 이 상수들을 사용하려는 클래스에서는 정규화된 이름(qualified name)을 쓰는 걸 피하고자 그 인터페이스를 구현하곤 합니다. 다음의 예를 봅시다. public interface PhysicalConstants { // 아보가드로 수 (1/몰) static ..
자바 8 전에는 기존 구현체를 깨드리지 않고는 인터페이스에 메서드를 추가할 방법이 없었습니다. 인터페이스에 메서드를 추가하면 보통은 컴파일 오류가 나는데, 추가된 메서드가 우연히 기존 구현체에서 이미 존재할 가능성은 아주 낮기 때문입니다. 자바 8에 와서 기존 인터페이스에 메서드를 추가할 수 있도록 디폴트 메서드를 소개했지만, 위험이 완전히 사라진 것은 아닙니다. 디폴트 메서드를 선언하면, 그 인터페이스를 구현한 후 디폴트 메서드를 재정의하지 않은 모든 클래스에서 디폴트 구현이 쓰이게 됩니다. 이처럼 자바에도 기존 인터페이스에 메서드를 추가하는 길이 열렸지만 모든 기존 구현체들과 매끄럽게 연동되리라는 보장은 없습니다. 자바 7까지의 세상에서는 모든 클래스가 "현재의 인터페이스에 새로운 메서드가 추가될 일..
자바가 제공하는 다중 구현 메커티즘은 인터페이스와 추상 클래스, 이렇게 두가지입니다. 자바 8부터 인터페이스도 디플트 메서드를 제공할 수 있게 되어 이제는 두 메커니즘 모두 인스턴스 메서드를 구현 형태로 제공할 수 있습니다. 자바 8에 추가된 기술 [4] deafult 메서드와 static 메서드 자바 8에는 다양한 기술들을 살펴보려고 하는데, 그 네 번째는 default 메서드와 static 메서드다. 자바 8부터 인터페이스의 추가할 수 있는 새로운 기능이다. API이나 스프링 코드가 이 기능 덕분에 kkoon9.tistory.com 둘의 가장 큰 차이는 추상 클래스가 정의한 타입을 구현하는 클래스는 반드시 추상 클래스의 하위 클래스가 되어야 한다는 점입니다. 자바는 단일 상속만 지원하니, 추상 클래스..
- Total
- Today
- Yesterday
- Spring
- programmers
- 테라폼
- BOJ
- 디자인 패턴
- 코테
- Kotlin
- node.js
- C++
- 클린 코드
- Java
- 이펙티브 자바
- 정규표현식
- Algorithm
- 알고리즘
- 이팩티브 자바
- Spring Boot
- MSA
- BAEKJOON
- Olympiad
- Effective Java
- 프로그래머스
- AWS
- kotest
- JPA
- 객체지향
- kkoon9
- 디자인패턴
- 백준
- 클린 아키텍처
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |