2015-02-01 8 views
0

Я не знаю, почему, но класс ниже не работает, если переменная-экземпляр экземпляра является частной, но если я оставляю ее закрытой, она работает.Spring + Scala + анонимный блок или класс

Отладка тест в разделе «SetField» Я мог видеть, что имя переменной экземпляра должен быть «текст», но он становится «ком $ тест $ SimpleTest $$ текст»

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», потому что, если я тоже уйду, это сработает.

+0

Что вы подразумеваете под "не работает"? Какая строка вызывает ошибку? Как удаление 'getOrElse' заставляет его работать? –

+0

Этот класс не работает, если вы попробуете запустить его. Линия выдает 'ReflectionTestUtils.setField (simpleTest," text "," abc ")'. Если я поместил переменную экземпляра 'simpleTest.text' анонимного блока, она будет работать. – Lira

ответ

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 где угодно, но внутри этого фрагмента кода.

+0

О '.getOrElse' на самом деле, если я выложу анонимный блок, он работает. Проблема в том, что переменная экземпляра находится внутри анонимного блока. Но я читаю статьи. – Lira

+0

в любом случае - компилятор может делать все, что захочет, с вашим частным полем, и это может измениться между версиями Scala, поэтому вы не можете использовать java-отражение - только scala reflectionn. – dk14

+0

о самом эксперименте - я подозреваю, что дело не в блоке - 'println (simpleTest.text)' тоже не должно работать - или какое-либо фактическое использование. Потому что, если вы просто запустили 'simpleTest.text' где-то между строками - компилятор знает, что значение не используется (на самом деле оно выводит предупреждение об этом). Во всяком случае, это '' встроенные 'скайца', и это не ошибка, поэтому мы не можем ее изменить. – dk14

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 
    } 
} 

Я не использую @ Упомянутый в этом примере, но в настоящем классе я. Поэтому, если вам нужно получить экземпляр, следуйте приведенным ниже инструкциям.

Пункт 1 -> если я надену @Autowired, он не работает, потому что, как сказано dk14 Scala compiler имеет право скомпилировать ваше личное поле в любой рабочий код Java. Таким образом, компилятор меняет имя поля при компиляции класса

Пункт 2 -> Я надеваю @ Упомянутый метод setter, он работает.

Смежные вопросы