2016-11-03 6 views
0

は、私は以下のクラス持っScalaのジェネリッククラス[_]パラメータ

def createMyClass(clazz: Class[_]) = 
    if(clazz.isEnum) 
    new MyClass(clazz) //compile error is here 
    else throw new IllegalArgumentException(s"$clazz is not an enum") 

をしかし、それはコンパイルすることを拒否する。実際には、タイプ境界を満たさないClass[_]のオブジェクトを渡します。実際にClassEnumを表すことをコンパイラに伝える方法はありますか?

Javaでは、私はキャスティングを行うだけですが、Scalaにはこのようなことに対処するためのより良い方法があると思います。

ところで、

new MyClass(clazz.asInstanceOf[Class[Enum[_]]]) 

は、私はメソッドのシグネチャを変更することはできません

いずれも動作しません。

答えて

1

をコンパイルしますTに同じタイプの制約を使用してメソッドを宣言します。必要に応じて

あなた実存タイプ

def createMyClass(clazz: Class[_]) = 
    if(clazz.isEnum) 
    new MyClass(clazz.asInstanceOf[Class[T] forSome { type T <: Enum[T] }]) 
    else throw new IllegalArgumentException(s"$clazz is not an enum") 

を使用して、それを行うことができます。しかし、それは実際には必要だ場合は、慎重に検討すべきです。 asInstanceOfは、必ずしも最後の手段であるとは限りません。

+0

非常に、ありがとう! – stella

1

は、それは私がメソッドのシグネチャを変更することはできません

def createMyClass[T <: Enum[T]](clazz: Class[T]) = 
    if(clazz.isEnum) new MyClass(clazz) 
    else throw new IllegalArgumentException(s"$clazz is not an enum") 

ScalaのREPL

scala> class MyClass[T <: Enum[T]](val clazz: Class[T]){ 
    def dummy = println(clazz.toString) 
    } 
defined class MyClass 

scala> def createMyClass[T <: Enum[T]](clazz: Class[T]) = 
    if(clazz.isEnum) 
     new MyClass(clazz) else throw new IllegalArgumentException(s"$clazz is not an enum") 
defined function createMyClass