2012-07-30 1 views
7

제네릭 스칼라 (2.9.2)를 사용하는 자바 메서드를 구현하고 싶습니다. 하지만 ... 실패하고 있습니다 스칼라, 일반 자바 메서드를 구현할 수 없습니다

자바 인터페이스 방법 :

public <T extends Number> void setAttribute(Key<T> key, Number value); 
그 방법을 구현하려는

스칼라 코드 :

def setAttribute[T <: Number](key: Key[T], value: Number) = { 
    setAttributeLocal(key, value) } 

private def setAttributeLocal[T](key: Key[T], value: T) = { 
    val stringValue = ConvertUtils.convert(value, classOf[String]).asInstanceOf[String] 
    session = session + (key.getValue() -> stringValue) 
} 

키는 다음과 같습니다

public class Key<T> 

을 그러나 이것은 컴파일되지 않습니다.

[error] found : mypackage.Key[T] 
[error] required: mypackage.Key[java.lang.Number] 
[error] Note: T <: java.lang.Number, but Java-defined class Key is invariant in type T. 
[error] You may wish to investigate a wildcard type such as `_ <: java.lang.Number`. (SLS 3.2.10) 
[error]  setAttributeLocal(key, value) 

무엇이 문제인지 알 수 없습니다. 어떤 제안/아이디어?

greez GarfieldKlon

+1

'Key '가 어떻게 보이는지 알아야합니다. 왜냐하면'public interface Key '을 사용하면 위의 코드가 잘 컴파일됩니다. –

+0

@GarfieldKlon 어떤 스칼라 버전을 사용하고 있습니까? –

+0

@ 0__ 어떤 버전에서 컴파일됩니까? –

답변

4

컴파일러가 setAttributeLocal에 전화와 불행이 나타납니다. setAttributeLocal에는 Key[Number]이 필요하지만 Key[_ <: T]을 제공하고 있습니다. Java-Land에서는 Key<? extends Number>Key<Number>으로 전달하려고 시도하고 있음을 의미합니다.

자바 또는 스칼라 정의에 따라 setAttributeLocalKey<? extends Number> 또는 Key[_ <: Number]을 수락하는 것이 좋습니다.

+0

@GarfieldKlon 나는 이것을 몇 번 읽어야했다. Ben이 제안하는 것은'setAttribute'를 수정하는 데 초점을 맞추면 잘못된 것을보고있을 수도 있다는 것이다. 설명 된 오류는'setAttribute'가 아니라'setLocalAttribute'에서 타입 문제입니다. 'setLocalAttribute'의 정의는 어떻게 생겼습니까? –

+0

@ 리차드 - 좋아요, 왜 이걸 재현 할 수 없었는지 설명합니다 –

+0

마지막으로이 솔루션을 추가했습니다 :'private def setAttributeLocal [T] (key : Key [T], value : Object)' – GarfieldKlon

1

여기 좀 이상해 보입니다. 그것은 키의 타입 T를 보존 나쁜/이상한 것 같다

def setAttribute[T <: Number](key: Key[T], value: T) = 
    setAttributeLocal(key, value) 

하지만 값을 사용하지 :

당신이 노력했다. 내 생각 엔 불변의 오류가 발생하는 곳이라고 생각합니다. Number 유형의 값을 T 키로 지정하려고 시도하고 있는데 ( Number의 경우 T을 전달할 수 있음을 알고있는 동안) NumberT으로 전달할 수없는 경우 컴파일러는 확실하지 않습니다.

더 많은 코드를 볼 수 있습니까?

+0

그건 옵션이 아니기 때문에 재정의가 아닙니다. – GarfieldKlon

+0

Java 및 Scala의 유형 인터페이스에는 제한 사항이 있습니다. 자바에서 여러분이하고있는 것은 unsound 타입이므로 Scala는 그것을 허용하지 않습니다. 계속해서 해당 유형 마법사를 사용하려면 자바 유형 시스템을 고수해야합니다. 미안합니다. – jsuereth

1

는 @jsuereth 이미 즉 setAttributesetAttributeLocal의 서명 간의 차이는 후자 인 반면 전자는하는 Key[T <: Number]을 허용하지만 될 정확히 열쇠와 Number 간다 값을 수정하는 것이 존재하고, 지적 더 유연하며 키와 값을 T <: Number으로 설정할 수 있습니다. 이것은 다소 이상하게 보입니다. 그리고 그 결정을 재고하고 싶을 것입니다. 또한 @Ben Schulz가 설명하는 문제로 이어진다.

어쨌든 컴파일러 (2.9.

MyI.java :

public interface MyI { 
    public <T extends Number> void setAttribute(Key<T> key, Number value); 
} 

Key.java :

public interface Key<T> { 
} 

Test.scala :

object Test extends App { 
    def setAttribute[T <: Number](key: Key[T], value: Number) = { 
    setAttributeLocal(key, value) } 

    private def setAttributeLocal[T](key: Key[T], value: Number) = { 
    /* Notice that value is now also of type Number. */ 
    } 
} 
) 다음 설치에 만족