I use a Java code-generator (unfortunately I cannot get rid of it) which spits out code like this:
abstract class Abs1 { //... }
abstract class Abs2 { //... }
interface I { //... }
public static final class C1 extends Abs implements I {
public final static Inner newInstance() { return Inner.create(); }
public final class Inner extends Abs2 {
private static Inner create() { return new Inner(); }
}
public final static C1 build() {
// builds the object instantiating some fields with defaults
}
}
final static class C2 extends Abs implements I {
// exactly same as in C1:
public final static Inner newInstance() { return Inner.create(); }
public final class Inner extends Abs2 {
private static Inner create() { return new Inner(); }
}
public final static C1 build() {
// builds the object instantiating some fields with defaults
}
}
I have many other classes like C1 and C2 in the same style. As you can see, every outer class (C1, C2 ...) has an Inner class, always named as Inner. Also, all InnerClasses extend the same abstract class.
I want to create instances of each of these outer-classes from Strings. I have a utility (Merger) that can merge an instance with it's String.
def createC1(str: String) = {
val ins = C1.newInstance
Merger(ins, str)
ins.build
}
def createC2(str: String) = {
val ins = C2.newInstance
Merger(ins, str)
ins.build
}
... this seemed like obvious code-duplication. So I wanted to take advantage of type-parameterization.
def build[A <: Abs](str: String) = {
val ins = A.newInstance // this obviously won't compile - but this is my intent
Merger(ins, str)
ins.build
}
So I could do: build[Cn](str)
How can I call the static Java method using the type parameter info ? I tried using ClassTag:
def build[A <: Abs : ClassTag](str: String) = {
val ins1 = (new A) // ins1 type is now A with Object, WAT ?
val ins2 = ins.asInstanceOf[A] // I do not want to do asInstanceOf but the compiler won't recognize that ins2 is an instance of A otherwise
// ins2 has access to newInstance method
// Not sure if the below code works, I had to actually try it :)
// Merger(str, ins2)
// ins2.build()
???
}
Why doesn't it infer the type in ins1 ?
EDIT: Make outer classes static.
public final class Inner extends Abs2have thestaticmodifier? I don't think that is legal without it.ClassTag.