2013-08-04 6 views
11

私が必要とTのインスタンスを作成するために、私は(私のコントロールを超えて)Javaメソッドを呼び出す必要があり、このメソッド内暗黙のClassTag [T]からClass [T]を取得するにはどうすればよいですか?

def retrieve[T](value: Option[T])(implicit ct: ClassTag[T]): T; 

ようなメソッドを持っているしたいと思いClass[T]

public <T> T construct(clazz: Class<T> /* other arguments */) { ... } 

Class[T]ClassTag[T]から取得するにはどうすればよいですか?最初にClassTagruntimeClassを使用できると思っていましたが、タイプはClass[_]で、Class[T]ではありません。または、コンパイラが自動的に提供できる他の暗黙的な値がありますか?Class[T]から取得できますか?

Odersky著は推測している
+6

Javaのリフレクションを使用するときは、鋳物を恐れてはなりません。 'asInstanceOf [Class [T]]'を実行するだけです。 –

答えて

14
getClass

Here is the ticketlinked forum discussion

また、キャストを使用することができます。

Here is the duplicate ticketgetClassが固定されている。 5.getClassもキャスト:

/** Return the class object representing an unboxed value type, 
* e.g. classOf[int], not classOf[java.lang.Integer]. The compiler 
* rewrites expressions like 5.getClass to come here. 
*/ 
def anyValClass[T <: AnyVal : ClassTag](value: T): jClass[T] = 
    classTag[T].runtimeClass.asInstanceOf[jClass[T]] 

制限は、私たちの素朴な期待も満たされていないされているClassTagthis question about pattern matching、を彷彿とさせます。

Class[A]への抵抗は、Scalaタイプとプラットフォーム間のインピーダンスの不一致を表しますか?

クラスタイプを指定すると、すべて実際に行うことができるのはnewInstanceです。しかし、コンストラクター・ミラーを使用したリフレクション・コールでは、自分のタイプを戻すことはできません。

scala> res24 reflectConstructor res25.asMethod 
res27: reflect.runtime.universe.MethodMirror = constructor mirror for Bar.<init>(): Bar (bound to null) 

scala> res27() 
res28: Any = [email protected] 

scala> bar.getClass.newInstance 
res29: Bar = [email protected] 

scala> classOf[Bar].newInstance 
res30: Bar = [email protected] 

これは公平ではないようです。

2008年のこのメールスレッドでは、Scalaでのキャスト数が少なくなると予想しています。

ところで、それは私が、コードのコメントを信じなかったが、ということはありません。

scala> 5.getClass 
res38: Class[Int] = int 

scala> :javap - 
    Size 1285 bytes 
    MD5 checksum a30a28543087238b563fb1983d7d139b 
    Compiled from "<console>" 

[省略]

9: getstatic  #27     // Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$; 
12: iconst_5  
13: invokestatic #33     // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer; 
16: getstatic  #38     // Field scala/reflect/ClassTag$.MODULE$:Lscala/reflect/ClassTag$; 
19: invokevirtual #42     // Method scala/reflect/ClassTag$.Int:()Lscala/reflect/ClassTag; 
22: invokevirtual #46     // Method scala/runtime/ScalaRunTime$.anyValClass:(Ljava/lang/Object;Lscala/reflect/ClassTag;)Ljava/lang/Class; 
25: putfield  #18     // Field res38:Ljava/lang/Class; 
28: return   
+0

これは良い研究ですが、良い答えではありません。リンク、引用符、ソースコード、逆アセンブル... 'ClassTag [T]'から 'Class [T]'をどうやって得るのですか? (私はそれを理解することができるという意味ですが、答えの最優先事項はこの質問に答えて、文脈を提供することだと思います) –

+1

@DanielDarabosそれはキャストを使用すると言います。 ClassTagからクラスへこの答えは、義務の呼び出しを超えて行きます。 OPは意見がありませんでした。 –

+0

_ "キャストを使用する" _はフォーラムからの推測の引用です。 "example"はScalaランタイム内部( 'ScalaRunTime.scala')からのコードスニペットであり、" this is you it it "という言葉を使わずに挿入されます。ファイル内の 'Class [T]'のローカルエイリアスである 'jClass [T]'を返しますが、答えの読者はそのことを知らない。とにかく、私は答えを批判したくない、私はちょうどフィードバックをしたいと思った。これは非常に洞察力のある答えです。 –

関連する問題