2

just searched everywhere. How do I create a new instance from String(name of the class) and return this instance? There indeed are answers yet they didn't answer how could I cast this instance to the type I want. For instance:

class ABC
{
  //some code
}

Now I want to create an instance using the name of the class "ABC"(Identical to val abc = new ABC()).

val mirror = universe.runtimeMirror(getClass.getClassLoader);
val classInstance = Class.forName("ABC");
val classSymbol = mirror.classSymbol(classInstance);
val classType = classSymbol.toType;//println(classType) gives ABC
/******this line does not work*****/
classInstance.newInstance().asInstanceOf[classType];
// not asInstanceOf[ABC]
/***********/

Because classInstance.newInstance() has type "Any", how could I convert it to the type "ABC"? Thank you!

TFBoy
  • 41
  • 1
  • 4

3 Answers3

0

Scala's syntax for typecasting is x.asInstanceOf[ABC], where x is your object (it will be classInstance.newInstance() in your code above) and ABC is the type you cast to. Note the brackets are square, not round - this is a parameterless method that takes a type argument.

Michał Kosmulski
  • 9,855
  • 1
  • 32
  • 51
  • Hi Micheal, thank you for your response. The problem is the class type is stored in parameter classType. I cannot write x.asInstanceOf[ABC] because it is dynamic. – TFBoy Apr 16 '14 at 22:24
  • If you don't know any details about type ABC, how are going to call any methods on its instances? In such a situation you could only use reflection, but for that you don't need to cast. If on the other hand you have type ABC's definition, you'll be better off using the type directly and avoiding `Class.forName()`. – Michał Kosmulski Apr 17 '14 at 05:36
0

I'm probably wrong, but I think what you're looking for doesn't make sense. Suppose, for the sake of argument, you could do this. The test question is: what are you going to do next? The compiler obviously doesn't know what class it is, so you can't call methods or access fields on it directly.

So I think you probably need to use reflection - either Scala or Java - and hence don't need asInstanceOf.

Ed Staub
  • 15,480
  • 3
  • 61
  • 91
0

Currently you can use a whitebox macro. It can return a type more precise than declared

import scala.language.experimental.macros
import scala.reflect.macros.whitebox

def newInstance(className: String): Any = macro newInstanceImpl

def newInstanceImpl(c: whitebox.Context)(className: c.Tree): c.Tree = {
  import c.universe._
  val classNameStr = className match {
    case q"${str: String}" => str
  }
  q"new ${TypeName(classNameStr)}"
}
class ABC

val x = newInstance("ABC")

// checking the type
x: ABC // compiles

How to obtain a Trait/Class from a string with its name

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66