자바 8 의 default 방법 상세 소개
자바 8 이 발 표 된 후에 인터페이스 에 새로운 방법 을 추가 할 수 있 지만 인 터 페 이 스 는 실현 류 와 호 환 될 수 있 습 니 다.이것 은 매우 중요 합 니 다.왜냐하면 당신 이 개발 한 라 이브 러 리 는 여러 개발 자 들 이 광범 위 하 게 사용 하고 있 을 것 입 니 다.자바 8 이전에 라 이브 러 리 에 인 터 페 이 스 를 발표 한 후에 인터페이스 에 새로운 방법 을 추가 하면 이 인터페이스의 응용 을 실현 하고 새로운 버 전의 인 터 페 이 스 를 사용 하면 붕 괴 될 위험 이 있다.
자바 8 이 있 으 면 이런 위험 은 없 지 않 습 니까?답 은 부정 적 이다.
인터페이스 에 default 방법 을 추가 하면 일부 구현 클래스 를 사용 할 수 없습니다.
우선 default 방법의 세부 사항 을 살 펴 보 자.
자바 8 에 서 는 인터페이스 에서 의 방법 이 실 현 될 수 있다(자바 8 의 static 방법 도 인터페이스 에서 이 루어 질 수 있 지만 이것 은 또 다른 화제 이다).인터페이스 에서 실 현 된 방법 을 default 방법 이 라 고 하 는데 키워드 default 을 수정자 로 표시 합 니 다.하나의 인 터 페 이 스 를 실현 할 때,그것 은 이미 인터페이스 에서 실 현 된 방법 을 실현 할 수 있 지만,이것 은 필요 한 것 이 아니다.이 종 류 는 default 방법 을 계승 합 니 다.인터페이스 가 바 뀌 었 을 때 실현 류 가 바 뀌 지 않 아 도 되 는 이유 다.
많이 물 려 받 을 때 는?
하나의 클래스 가 하나 이상(예 를 들 어 두 개)인 터 페 이 스 를 실 현 했 고 이런 인터페이스 에 똑 같은 default 방법 이 있 을 때 일이 복잡 해진 다.클래스 계승 은 어떤 default 방법 입 니까?아무 도 아니 야!이러한 상황 에서 클래스 는 자신(직접 또는 트 리 의 더 높 은 층 을 계승 하 는 클래스)이 default 방법 을 실현 해 야 한다(가능).
하나의 인터페이스 가 default 방법 을 실현 하고 다른 인터페이스 가 default 방법 을 abstract 로 설명 할 때 도 마찬가지 입 니 다.자바 8 은 불명확 한 것 을 피하 고 엄밀 함 을 유지 하려 고 한다.만약 하나의 방법 이 여러 인터페이스 에 성명 이 있다 면,어떠한 default 실현 도 계승 되 지 않 을 것 입 니 다.컴 파일 시 오류 가 발생 할 것 입 니 다.
그러나,만약 당신 이 이미 당신 의 종 류 를 컴 파일 했다 면,컴 파일 할 때 오류 가 발생 하지 않 을 것 입 니 다.이 점 에서 자바 8 은 일치 하지 않 는 다.그 이 유 는 여러 가지 이유 가 있 습 니 다.여기 서 저 는 상세 하 게 설명 하거나 깊이 있 는 토론 을 하고 싶 지 않 습 니 다.(버 전이 발표 되 었 고 토론 시간 이 너무 길 어서 이 플랫폼 은 이런 토론 을 한 적 이 없습니다)
1.만약 당신 이 두 개의 인터페이스 가 있다 면,하 나 는 실현 류 입 니 다.2.그 중의 한 인 터 페 이 스 는 default 방법 m()를 실현 했다.3.인터페이스 와 실현 클래스 를 컴 파일 한다.4.m()방법 이 포함 되 지 않 은 인 터 페 이 스 를 수정 하고 m()방법 을 abstract 로 설명 합 니 다.5.수 정 된 인 터 페 이 스 를 따로 재 컴 파일 합 니 다.6.실행 실현 클래스.
위의 상황 하에 서 류 는 정상적으로 운행 할 수 있다.그러나 수 정 된 인터페이스 로 다시 컴 파일 할 수 는 없 지만 오래된 인터페이스 로 컴 파일 하면 실행 할 수 있다.다음
1.abstract 방법 m()을 포함 하 는 인 터 페 이 스 를 수정 하고 default 을 만 듭 니 다.2.수 정 된 인 터 페 이 스 를 컴 파일 합 니 다.3.실행 클래스:실 패 했 습 니 다.두 인터페이스 가 같은 방법 에 default 실현 을 제공 할 때 이 방법 은 호출 될 수 없습니다.실현 클래스 가 이 default 방법 을 실현 하지 않 는 한(직접 실현 하거나 트 리 의 더 높 은 층 을 계승 하여 실현 합 니 다).
하지만 이 종 류 는 호 환 된다.새 인 터 페 이 스 를 사용 한 상태 에서 불 러 올 수도 있 고 실행 할 수도 있 습 니 다.두 인터페이스 에 디 폴 트 가 호출 되 지 않 는 한 디 폴 트 구현 방법 이 있 습 니 다.
인 스 턴 스 코드:
위의 예 를 보 여주 기 위해 저 는 C.자바 에 게 테스트 디 렉 터 리 를 만 들 었 습 니 다.그 아래 에는 3 개의 키 디 렉 터 리 가 있 습 니 다.I1.자바 와 I2.자바 를 저장 하 는 데 사 용 됩 니 다.테스트 디 렉 터 리 에는 클래스 C 의 소스 코드 C.자바 가 포함 되 어 있 습 니 다.base 디 렉 터 리 는 컴 파일 하고 실행 할 수 있 는 그 버 전의 인 터 페 이 스 를 포함 하고 있 습 니 다.I1 은 default 이 실 현 된 m()방법 을 포함 하고 I2 는 어떠한 방법 도 포함 하지 않 습 니 다.
실현 류 는 main 방법 을 포함 하고 있 기 때문에 우 리 는 테스트 에서 그것 을 실행 할 수 있다.명령 행 인자 가 존재 하 는 지 확인 합 니 다.그러면 우 리 는 m()와 m()를 호출 하지 않 는 테스트 를 편리 하 게 수행 할 수 있 습 니 다.
~/github/test$ cat C.java
public class C implements I1, I2 {
public static void main(String[] args) {
C c = new C();
if(args.length == 0 ){
c.m();
}
}
}
~/github/test$ cat base/I1.java
public interface I1 {
default void m(){
System.out.println("hello interface 1");
}
}
~/github/test$ cat base/I2.java
public interface I2 {
}
다음 명령 행 을 사용 하여 컴 파일 실행:~/github/test$ javac -cp .:base C.java
~/github/test$ java -cp .:base C
hello interface 1
compatible 디 렉 터 리 에는 abstract 방법 m()이 있 는 I2 인터페이스 와 수정 되 지 않 은 I1 인터페이스 가 포함 되 어 있 습 니 다.~/github/test$ cat compatible/I2.java
public interface I2 {
void m();
}
이것 은 컴 파일 류 C 에 사용 할 수 없습니다.~/github/test$ javac -cp .:compatible C.java
C.java:1: error: C is not abstract and does not override abstract method m() in I2
public class C implements I1, I2 {
^
1 error
잘못된 정 보 는 매우 정확 하 다.이전 컴 파일 에서 얻 은 C.class 가 있 기 때문에 compatible 디 렉 터 리 의 인 터 페 이 스 를 컴 파일 하면 실행 가능 한 두 개의 인 터 페 이 스 를 얻 을 수 있 습 니 다.
~/github/test$ javac compatible/I*.java
~/github/test$ java -cp .:compatible C
hello interface 1
세 번 째 는 wrong 이라는 디 렉 터 리 입 니 다.포 함 된 I2 인터페이스 도 m()방법 을 정 의 했 습 니 다.
~/github/test$ cat wrong/I2.java
public interface I2 {
default void m(){
System.out.println("hello interface 2");
}
}
우 리 는 그것 을 지루 하지 않 게 번역 해 야 한다.비록 m()방법 이 두 번 정의 되 었 지만,실현 클래스 는 여전히 실행 할 수 있 습 니 다.그것 이 여러 번 정 의 된 방법 을 호출 하지 않 았 다 면,우리 가 m()방법 을 호출 하기 만 하면 즉시 실패 할 것 입 니 다.이것 은 우리 가 사용 하 는 명령 행 인자 입 니 다.
~/github/test$ javac wrong/*.java
~/github/test$ java -cp .:wrong C
Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting
default methods: I1.m I2.m
at C.m(C.java)
at C.main(C.java:5)
~/github/test$ java -cp .:wrong C x
~/github/test$
결론.인터페이스 에 default 을 추가 하여 실 현 된 라 이브 러 리 를 자바 8 환경 에 이식 할 때 문제 가 없 을 것 입 니 다.최소한 자바 8 라 이브 러 리 개발 자가 집합 류 에 default 방법 을 추가 할 때 는 그렇게 생각 합 니 다.라 이브 러 리 를 사용 하 는 프로그램 은 default 방법 이 없 는 자바 7 라 이브 러 리 에 의존 합 니 다.여러 개의 다른 라 이브 러 리 를 사용 하고 수정 할 때 작은 확률 로 충돌 이 발생 할 수 있다.어떻게 해야만 피 할 수 있 습 니까?
예전 처럼 당신 의 라 이브 러 리 를 설계 하 세 요.default 방법 에 의존 할 때 방심 하지 마 세 요.만부득이 사용 하지 마라.다른 인터페이스 와 충돌 하지 않도록 현명 한 선택 방법 명.우 리 는 자바 프로 그래 밍 에서 이 특성 을 어떻게 사용 하여 개발 하 는 지 배 울 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.