0

Here is my code

package a1

trait Algorithm[T] {
  def someMethod(a: Int): T
}
package b2

import a1.Algorithm

class Word2Vec[T] extends Algorithm[T] {
  def someMethod(a: Int): T = a.asInstanceOf[T]
}
package c3

import a1.Algorithm

object Main {
  def main(args:Array[String]) = {
    val word2vec:Algorithm[Float] = Class.forName("b2.Word2Vec").newInstance().asInstanceOf[Algorithm[Float]]
    val a = word2vec.someMethod(123)
    println(a)
  }
}

and I got this:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Float
    at scala.runtime.BoxesRunTime.unboxToFloat(BoxesRunTime.java:107)
    at c3.Main$.main(Main.scala:8)
    at c3.Main.main(Main.scala)

by the way,How could I get a type when I get a string name. I have an "int" and I want to pass type Int as the type parameter for generic

3
  • 1
    Reflection at runtime is not recommended. Commented Nov 27, 2019 at 9:28
  • First reflection is a bad idea, is slow and unsafe, why do you need it? Why not just instantiating the class on code. PS: Lately there had been a couple of similar questions, are they related in anyway? Same project? - Second, asInstanceOf is a big code smell especially in this case it seems it will never work. - Finally, how did you expect it to work if you passed an Int and asked for a Float? Commented Nov 27, 2019 at 11:38
  • 1
    @LuisMiguelMejíaSuárez "Finally, how did you expect it to work if you passed an Int and asked for a Float?" Int is passed to def someMethod(a: Int)... and Float is T in Word2Vec[T]. There's no problem in casting scala.Int to scala.Float: 123.asInstanceOf[Float]. It's java.lang.Integer that can't be casted to java.lang.Float. Commented Nov 27, 2019 at 19:14

1 Answer 1

1

The following code with Int doesn't throw exception

val word2vec = Class.forName("b2.Word2Vec").newInstance().asInstanceOf[Algorithm[Int]]
val a = word2vec.someMethod(123)
println(a) // 123

or with _

val word2vec = Class.forName("b2.Word2Vec").newInstance().asInstanceOf[Algorithm[_]]
val a = word2vec.someMethod(123)
println(a) // 123

Actually Class.forName + newInstance is not Scala reflection, it's Java reflection used in Scala. Scala reflection is different.

by the way,How could I get a type when I get a string name. I have an "int" and I want to pass type Int as the type parameter for generic

I'm not sure this can be done with Java reflection. With Scala reflection

import scala.reflect.runtime.universe._
val mirror = runtimeMirror(this.getClass.getClassLoader)
val classSymbol = mirror.staticClass("b2.Word2Vec") // class Word2Vec
// if string is "int"
internal.typeRef(NoPrefix, classSymbol, List(typeOf[Int])) // Word2Vec[Int]
// if string is "float"
internal.typeRef(NoPrefix, classSymbol, List(typeOf[Float])) // Word2Vec[Float]
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.