Spring + Scala +匿名块或类

时间:2015-02-01 23:52:17

标签: java spring scala

我不知道为什么,但如果实例变量文本是私有的,下面的课程不起作用,但是如果我省略私有,它就有效。

在第34节中调试测试; setField"我可以看到实例变量名称应为" text"但它变成了" com $ test $ SimpleTest $$ text"

package com.test
import org.testng.annotations.Test
import org.springframework.test.util.ReflectionTestUtils

class SimpleTest {
  private var text = ""

  @Test
  def testValueOfX(): Unit = {
    val simpleTest = new SimpleTest
    ReflectionTestUtils.setField(simpleTest,"text", "abc")

    println(
      Option[String](null)
        .map(v => v + " 123")
        .getOrElse {
          simpleTest.text + " 321"
    })
  }
}

我认为这个问题无论如何都是" getOrElse"因为如果我也遗漏了,那就行了。

2 个答案:

答案 0 :(得分:2)

Scala编译器有权将您的私有字段编译成任何可用的java代码,因为它不会影响互操作性(如果您不做任何技巧)。 Spring setField实际上做了这样的技巧,因为它使你的私有字段可访问(setAccessible(true)里面)。公共字段总是在编译,以便为您提供适当的Java接口。

使用http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html处理Scala反射。 this article也可能会有所帮助。

Here解释了为什么scalac为私有字段使用其他名称。

P.S。删除.getOrElse(text)使其有效的原因是因为您不在任何地方使用text,而是在此段代码中。

答案 1 :(得分:0)

这个类只是为了显示问题,实际上它与真实类有很大的不同。所以我改变策略以通过@Autowired方法接收一个实例而不是@Autowired一个字段。

package com.test
import org.testng.annotations.Test
import org.springframework.test.util.ReflectionTestUtils

class SimpleTest {
  // item 1
  private var text = ""

  @Test
  def testValueOfX(): Unit = {
    val simpleTest = new SimpleTest
    ReflectionTestUtils.invokeSetterMethod(simpleTest, "text", "abc")

    println(
          Option[String](null)
        .map(v => v + " 123")
        .getOrElse {
        simpleTest.text + " 321"
      })
  }
  // item 2
  def setText(text: String): Unit = {
    this.text = text
  }
}

我不是在这个样本中使用@Autowired,而是在我真正的课堂上。因此,如果您需要获取实例,请按照以下说明操作。

项目1 - >如果我加上@Autowired它不起作用,因为像 dk14 Scala编译器有权将你的私有字段编译成任何工作的java代码。因此,编译器在编译类

时会更改字段的名称

第2项 - >我在setter方法中加入@Autowired,它可以工作。