2011-10-08 2 views
4

"부울"유형과 "부울"유형의 클래스를 일치시키는 방법은 무엇입니까?

다음 코드를 고려하십시오. retType
object U { def foo(s:String) = true } 
val boolType = Class.forName("java.lang.Boolean")  
val retType = U.getClass.getMethods.find(_.getName == "foo").get.getReturnType 
boolType == retType // evaluates to false (*) 
println (boolType) // prints "class java.lang.Boolean" 
println (retType) // prints "boolean" 

(*)(*)으로 표시된 줄에서 boolType와 일치하도록합니다. 박스형 및 박스 화되지 않은 유형의 클래스를 자동으로 동일하게 만드는 방법은 무엇입니까?

[편집 :] 나는 이것이 최선의 해결책이라고 생각하지 않지만, 한가지 방법은 비교를하는 것이다.

[편집 2 :] 컨텍스트 : 나는 자동으로 메소드를 호출하는 코드를 작성 중이다. 양식 이름을 기반으로합니다. 코드는 메서드에서 반환 형식 등을 추출하고 적절한 대답을 반환해야합니다. 예를 들어 다음 스 니펫이 사용됩니다.

object someObject {} 
val validTypes:Array[Class[_]] = Array(Class.forName("java.lang.String"), 
           someObject.getClass, 
           Class.forName("java.lang.Boolean")) 
object U { def foo(s:String) = true } // can contain more methods 

def getRetType(name:String) = 
    U.getClass.getMethods.find(_.getName == name).get.getReturnType 

println ("Type is "+(if (validTypes.contains(getRetType("foo"))) "valid" else "invalid")) 
+0

흥미로운 질문이지만 어떤 맥락에서 필요합니까? 컴파일 타임이나 런타임에 확인하길 원하십니까? – paradigmatic

+0

@paradigmatic 검사는 런타임에 완료 될 것입니다. – Jus12

답변

3

Java reflection은 프리미티브 리턴 유형을 나타내려고 할 때 래퍼 클래스와 다른 인스턴스 인 Class을 사용합니다. 따라서 Java에서 boolean 반환 유형은 java.lang.Boolean.TYPE (Java에서는 boolean.class으로, 그리고 Scala에서는 classOf[Boolean]으로 액세스 할 수도 있음)으로 표시됩니다.

그래서 당신은

scala> U.getClass.getMethods.find(_.getName == "foo").get.getReturnType == 
    java.lang.Boolean.TYPE 
res7: Boolean = true 

편집을 원하는 : 나는 classOf[Boolean]과 비교하면 덜 JVM 특정 솔루션이 될 것이라고 생각한다.

+0

감사! 'java.lang.Boolean.TYPE'을 사용하면 효과가 있습니다! – Jus12

2

, java.lang.Boolean 레퍼런스 타입이다. 귀하의 루틴은 자바 프리미티브 boolean 인 스칼라 Boolean을 반환합니다. 그 중 하나는 JVM의 클래스가 아닙니다. 그 유형은 java.lang.Boolean.TYPE이고, classOf[Boolean] (java.lang.Boolean.class, java)이 아니며, 이는 Class.forName("java.lang.Boolean")으로 얻을 수 있습니다.

+0

자바 프리미티브 boolean의 클래스는 boolean.class이며 실제로 JVM에 존재합니다. – EJP

+0

이것이 존재하지 않는다고는 생각하지 않습니다. 원시는 클래스가 아니라고 말합니다. –

2

유일한 해결책은 명시 적 매핑을 사용하는 것입니다. "(자동으로) 박스형 및 박스 화되지 않은 유형의 클래스를 동일화하는 방법"을 묻는 때, 나는 비교 함수를 정의하는 우아한 방법을 보여줍니다.

먼저 Class.forName 대신 형식을 컴파일 할 때 classOf[Type]을 사용할 수 있습니다. 이 사용하면 박스 유형에 언 박싱의로 표준화 매핑을 정의 할 수 있습니다

import java.{lang => jl} 
val map = Map[Class[_], Class[_]](classOf[Boolean] -> classOf[jl.Boolean], 
    classOf[Int] -> classOf[jl.Integer]) //XXX add other entries 

그런 다음 당신은 비교 함수를 정의 할 수 있습니다 :

def cmp(lhs: Class[_], rhs: Class[_]) = 
    //Canonicalize before comparing 
    map.getOrElse(lhs, lhs) == map.getOrElse(rhs, rhs) 

을 그리고 테스트 :

scala> cmp(classOf[Boolean], classOf[jl.Boolean]) 
cmp(classOf[Boolean], classOf[jl.Boolean]) 
res13: Boolean = true 
scala> cmp(classOf[Boolean], classOf[jl.Integer]) 
cmp(classOf[Boolean], classOf[jl.Integer]) 
res16: Boolean = false 

것은 명확히하기 위해 classOfBoolean.TYPE 사이의 관계는 몇 가지 REPL 상호 작용입니다.

scala> classOf[java.lang.Boolean] == java.lang.Boolean.TYPE 
res7: Boolean = false 

scala> classOf[Boolean] == java.lang.Boolean.TYPE 
res8: Boolean = true 
+0

좋은 답변입니다. – Jus12

관련 문제