2011-08-29 1 views
8

Java Generics를 사용하지 않는 경우 동일한 클래스에서 반환 유형 만 다른 두 가지 메소드를 사용할 수 없다고 생각합니다.제네릭을 사용하여 메서드 오버로드를 수행하고 메서드 서명의 제네릭 형식 만 변경할 수 있습니까?

즉,이 불법 것 : 그런 다음 두 가지 방법이 존재한다면 서로 다른 인터페이스를 구현할 수 제네릭 형식을 돌려주는 메소드를 오버로드 할 때

public HappyEmotion foo(T emotion) { 
    // do something 
} 

public SadEmotion foo(T emotion) { 
    // do something else 
} 

이 같은 사실인가요 같은 클래스의 정의 :

public <T extends Happy> T foo(T emotion) { 
    // do something 
} 

public <T extends Sad> T foo(T emotion) { 
    // do something else 
} 

이 불법겠습니까?

+2

컴파일하려고 했습니까? 컴파일러는 합법적이고 불법적 인 것을 즉시 알려줍니다. 더 나은 질문은 '왜 불법입니까?'입니다. 당신이 그 이유를 이해하지 못한다면. –

답변

5

입력 매개 변수가 너무 종류에 따라 다릅니다 때문에 법적이다 .. 이러한 이유로

, 다음,

public <T extends Happy> T foo(T emotion) { 
    // do something 
} 

public <T extends Sad> T foo(T emotion) { 
    // do something else 
} 

법적으로 허용되지만 다음은 아닙니다

public <T extends Happy> String foo(T emotion) { 
    // do something 
} 

public <T extends Happy> T foo(T emotion) { 
    // do something else 
} 

감사 ...

2

이것은 잘 돌아갔다.

public class Main { 
    public static void main(String[] args){ 
     Main main = new Main(); 
     main.foo("hello"); 
     main.foo(new Integer(5)); 
    } 

    public <T extends String> T foo(T emotion) { 
     return (T) "test"; 
    } 

    public <T extends Integer> T foo(T emotion) { 
     Integer integer = 5; 
     return (T) integer; 
    } 
} 
2

컴파일은되지만, 문제가되는 부분은 해피 또는 슬픈 중 하나가 다른 쪽의 수퍼 클래스 인 경우입니다.

는 예를 들어, 다음은 컴파일 :

public <T extends Number> T sayHi() { 
    System.out.println("number"); 
    return null; 
} 

public <T extends Integer> T sayHi() { 
    System.out.println("integer"); 
    return null; 
} 

을하지만, 다음과 같은 컴파일하려고 할 때 문제가 실행

이 경우
Integer test = sayHi(); 

, 당신은 단순히에 <Integer>를 추가 할 수 없습니다 왜냐하면 Integer는 여전히 Number와 Integer이기 때문입니다. 다음은 해피 객체와 비자 반대의 인스턴스가 될 수없는 슬픈 대상으로 한 그래서 기본적으로

Double test2 = <Double>sayHi(); 

를 컴파일 그러나

, 당신의 코드 또는 앞에 오래 당신이 그것을 전화로 작동합니다 메소드 이름의.

+0

어떻게 동일한 메소드 서명을 가지고 있지만 반환 유형이 다른 두 개의 메소드를 작성하여 컴파일한다고해서 메소드 오버로드 개념에 완전히 위배됩니다 –

1

generic을 사용하여 Java에서 메소드를 구별 할 수 있습니다. JVM은이 유형을 볼 수 없지만 인수 또는 반환 유형이 다른 경우 Sun/Oracle 컴파일러에서 여전히 컴파일됩니다. 이것은 IBM/eclipse 컴파일러에서는 컴파일되지 않습니다.

바이트 코드 수준에서 원하는 것을 나타냅니다. http://vanillajava.blogspot.com/2011/02/with-generics-return-type-is-part-of.html

1

다른 사람들처럼 이것은 합법적입니다. 그러나 유형이 서로 확장 될 때 어떤 일이 발생하는지 지적하고 싶습니다.

interface Emotion {} 
interface Happy extends Emotion {} 

그리고 두 가지 기능 : 객체가 감정에 부합하는 경우

<T extends Emotion> void foo(T obj) {} // Referred as foo1 
<T extends Happy> void foo(T obj) {} // Referred as foo2 

JVM은 선택합니다

의 우리가 두 개의 인터페이스를 가지고 있다고 가정 해 봅시다 (단지 서명을 변경뿐만 아니라 클래스 작동) foo1. 오브젝트가 Happy를 준수하면 JVM은 foo2가 아닌 foo1을 선택합니다. 우선 순위에 유의하십시오. 이것이 JVM이 모호성을 해결하는 방법입니다. 그러나 이것은 generic 매개 변수를 인수로 전달할 때만 유효합니다.

관련 문제