0

在 Scala 2.10 之前,我有

class A {
    class B(b: Int) {
    }
}

并在代码中的某处重新创建 B 类

val bCtor = bInstance.getClass.getConstructor(classOf[Int])
bCtor.newInstance ...

一切都很好。有签名public A$B(Int)

现在构造函数有 2 个!!!论据。它有一个新的签名public A$B(A,Int)。类型 A 的参数是什么?我无法从我的函数访问 A 类。它有什么解决方法吗?

例如带有参数的 newInstance - 它不再适用于内部类

4

4 回答 4

3

注意不要将 java 内部类与 scala 路径相关类型混淆(来自Programming In ScalaBook):

依赖于路径的类型类似于 Java 中的内部类类型的语法,但有一个关键的区别:依赖于路径的类型命名为外部对象,而内部类类型命名为外部

因此,在您的情况下,bInstance 与 aInstance 有关。

我的假设是 aInstance 是作为第一个参数传递给此构造函数的对象。

于 2013-01-18T14:57:14.163 回答
1

首先,添加A作为第一个构造函数参数也是它在 Java 中的工作方式:

如果此 Class 对象表示在非静态上下文中声明的内部类,则形式参数类型包括显式封闭实例作为第一个参数。

第二,

类型 A 的参数是什么?我无法从我的函数访问 A 类。

如果您有一个B(从您的示例中可以看出),那么您可以访问它的封闭实例(它似乎没有正式记录,因此在 Java 的未来版本中可能会发生变化):

val aInstance = bInstance.getClass.getDeclaredField("this$0").get(bInstance)
bCtor.newInstance(aInstance, ...)

如果你不这样做,那么你不能创建一个B(没有一个A),但你不应该能够。您希望此代码返回什么?

class A(foo: Int) {
  class B {
    def bar = foo
  }
}

classOf[A#B].getConstructor().newInstance().bar
于 2013-01-19T04:31:15.800 回答
1

您可以使用不受约束的自类型注释来有一种方法可以this从 B 中引用 A 的版本(this现在指的是 B 实例)。

package rrs.scribble

object  OuterInner {
  class Outer { oThis =>
    class Inner {
      def identify { printf("I am %s; I'm inside of %s%n", this, oThis) }
    }
    val inner = new Inner
  }

  def oiTest {
    val o1 = new Outer
    o1.inner.identify
  }
}

在 REPL 中:

Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_37).

scala> import rrs.scribble.OuterInner._
import rrs.scribble.OuterInner._

scala> oiTest
I am rrs.scribble.OuterInner$Outer$Inner@63d0d313; I'm inside of rrs.scribble.OuterInner$Outer@22d1b797
于 2013-01-18T15:06:16.837 回答
0

@evantill 是对的, is 的唯一构造B函数A$B.<init>(A, Int)。所以bInstance.getClass.getConstructor(classOf[A], classOf[Int])有效。

于 2013-01-18T15:11:03.867 回答