2012-05-01 2 views
4

저는 보통 Java에 익숙하지 않은 C# 개발자이고 Generics를 사용하여 일부 코드를 설정하려고합니다. 나는 보통의 C# 개발자 해요,X가 T와 일치해야하더라도 X를 T로 변환 할 수 없습니까?

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Type mismatch: cannot convert from x.MyDerived to T 

at x.Main.getMeStuff(Main.java:14) 
at x.Main.main(Main.java:9) 

로 말했다, 그래서 코드는 먼저 눈에 잘 보이는 :

// Main.java 
public static void main(String[] args) { 
    MyBase my = getMeStuff(); 
    System.out.println(my.getSomething()); 
} 

private static <T extends MyBase> T getMeStuff(){ 
    return new MyDerived(123); 
} 

// MyBase/MyDerived.java 
public class MyBase { 
    private final int something; 

    protected MyBase(int something) { this.something = something; } 

    public int getSomething() { return something; } 
} 

public class MyDerived extends MyBase { 
    public MyDerived(int something) { super(something); } 
} 

이 컴파일에 실패 : 내 데모 코드는 다음과 같습니다. getMeStuff를 변경하여이 오류를 "해결할"수 있습니다 (T)에 캐스트를 추가 할 수 있지만 정말 필요한 캐스트? 내가 뭔가를 잊은 것처럼 조금 냄새가 난다.

+4

고정 된 알려진 유형을 반환하는 경우 왜 제네릭을 사용합니까? –

+0

@Oli 실제 구현이 더 복잡하기 때문에 많은 유형 중 하나를 반환 할 수 있기 때문에 (리플렉션을 통해 인스턴스화 된 클래스 ) –

답변

5

문제는 반환 형식이 MyBase에서 파생되는 모든 항목 일 수 있으며 사용자가 특별히 MyDerived에 입력 한 것입니다. MyDerived는 캐스트가없는 C#에서도 작동하지 않습니다. 호출자는 대신 SomeOtherDerived를 지정할 수 있었지만 MyBase에서 파생되었지만 MyDerived와는 아무 관련이 없습니다.

public class MyBase{} 
public class MyDerived extends MyBase{} 
public class SomeOtherDerived extends MyBase{} 
public static <T extends MyBase> T getAnything(){ return (T)new MyDerived(); } 

public static void main(String[] args) { 
    SomeOtherDerived instance = getAnything(); //This is legal and bad 
} 

그것은이 아주 나쁜 일이 명시 적으로 제공되지 것 모든 종류를 호출 할 때 쉽게 런타임 예외가 발생할 수 있습니다, 심지어 캐스트, 점에 유의하는 것도 중요합니다. 이것은 일반화 된 상황에서 무엇이 필요한지 매우 구체적인 유형을 박살내어 제네릭 개념에 어긋나게됩니다.

1

Java Generics는 유형 안전을 확보하는 데 도움을 드리고자합니다.

평행선을 사용합시다 : <T extends MyUIControl>을 작성하고 한 번에 MyButton과 그 밖의 다른 곳에서 MyPanel을 사용한다고 가정 해 봅시다 - 안전하게 전송할 수 없습니다.

컴파일러는 이러한 상황을 코드에서 인식했습니다.

관련 문제