2009-10-27 6 views
8

J'essaie d'obtenir un équivalent réel pour Java public static final dans Scala pour utiliser TwiP.Scala: finale statique publique dans une classe

Création d'un val dans un object ne fonctionne pas pour moi, parce que cela fait partie d'une nouvelle classe générée Example$.class et twip ne peut pas y accéder de la classe Example.class.

Voici un exemple d'une classe Java, je suis en train de port à Scala:

public static final String[] MY_STRINGS = { "A", "B", "C" }; 

@Test 
public void myTest(@Values("MY_STRINGS") String string) { 
    ... 
} 

Mais je ne sais pas comment le port du public static final à Scala. Si c'est un val dans un objet comme ici

@RunWith(classOf[TwiP]) 
class Foo { 

    import Foo.MY_STRINGS 

    @Test 
    def testTwiP(@Values("MY_STRINGS") value: String): Unit = { 
    println("I'm testing value " + value + ".") 
    } 

} 

object Foo { 
    val MY_STRINGS = Array("A", "B", "C") 
} 

-je obtenir que l'exception suivante:

net.sf.twip.internal.TwipConfigurationError: 
there is no method or field 'MY_STRINGS' named in the @Values annotation of Parameter#1 

Comment puis-je résoudre le problème en utilisant Scala?

+0

Est-ce que TwiP = http://twip.sourceforge.net/? –

+0

Si oui, http://code.google.com/p/scalacheck/ est peut-être plus approprié? –

+0

Oui, c'est ce twip. Je vais vérifier scalacheck. Merci pour le lien. – renfis

Répondre

1

Si vous utilisez un var, vous pouvez créer votre propre getter et setter, et si la valeur est déjà définie, ne le changez pas.

Cela peut ne pas être la meilleure approche, mais il serait utile que vous puissiez expliquer pourquoi vous voulez utiliser public static final sur une variable, car une meilleure solution pourrait alors être plus évidente.

+0

Bonjour James, merci pour votre commentaire. J'essaie de faire ce qui suit dans Scala: public static final Chaîne [] MY_STRINGS = {"A", "B", "C"}; @Test myTest public void (@Values ​​("MY_STRINGS") string String) { ...} http://twip.sourceforge.net/howto.html Mais je ne sais pas comment porter la finale statique publique à Scala. Si c'est un val dans un objet, je reçois seulement ce qui suit: net.sf.twip.internal.TwipConfigurationError: il n'y a pas de méthode ou de champ 'myStrings' nommé dans l'annotation @Values ​​du paramètre # 1 – renfis

+0

@renfis - Vous pouvez vouloir mettre cette information dans votre question, formatée correctement, pour le rendre plus facile à lire. –

+0

Merci. Je l'ai fait. – renfis

10
object Foo{ 
    val MY_STRINGS=Array("A","B","C") 
} 
class Foo{ 
    import Foo.MY_STRINGS 
} 

La définition val dans l'objet compagnon crée votre variable public static final, et la déclaration import lui donne un alias facile agréable dans le code que vous utilisez pour écrire la classe.

Notez que la variable public static final dans Scala compilera toujours pour ressembler à un appel de méthode statique si vous appelez ce code à partir de Java.

Editer: Je me trompe légèrement à cause d'un bug dans Scala 2.7, que je démontre en détail dans une autre réponse.

+0

Merci pour le tipp. Je l'ai essayé et l'ai ajouté à ma question. Mais ça ne marche pas pour moi. :( – renfis

+0

Cela est dû au fait que scala n'expose pas une variable en tant que variable - elle l'expose en tant que méthode.Vous devez trouver une version de l'annotation @values ​​qui appelle une méthode et utilise les valeurs renvoyées par la méthode –

+0

Vous voulez dire, la version actuelle de TwiP ne fonctionnera pas avec Scala? Dommage – renfis

3

Le code suivant Scala:

class Foo{ 
    import Bar.MY_STRINGS 
} 
object Bar{ 
    val MY_STRINGS=Array("A","B","C") 
} 

Génère les classes Java suivantes:

public final class Bar extends java.lang.Object{ 
    public static final java.lang.String[] MY_STRINGS(); 
    public static final int $tag()  throws java.rmi.RemoteException; 
} 
public final class Bar$ extends java.lang.Object implements scala.ScalaObject{ 
    public static final Bar$ MODULE$; 
    public static {}; 
    public Bar$(); 
    public java.lang.String[] MY_STRINGS(); 
    public int $tag()  throws java.rmi.RemoteException; 
} 
public class Foo extends java.lang.Object implements scala.ScalaObject{ 
    public Foo(); 
    public int $tag()  throws java.rmi.RemoteException; 
} 

Le code suivant Scala:

class Foo{ 
    import Foo.MY_STRINGS 
} 
object Foo{ 
    val MY_STRINGS=Array("A","B","C") 
} 

génère les classes Java suivantes:

public class Foo extends java.lang.Object implements scala.ScalaObject{ 
    public Foo(); 
    public int $tag()  throws java.rmi.RemoteException; 
} 
public final class Foo$ extends java.lang.Object implements scala.ScalaObject{ 
    public static final Foo$ MODULE$; 
    public static {}; 
    public Foo$(); 
    public java.lang.String[] MY_STRINGS(); 
    public int $tag()  throws java.rmi.RemoteException; 
} 

Le fait que les membres statiques ne soient pas définis dans la classe lorsque l'objet porte le même nom que la classe est Scala Bug #1735 et il est corrigé dans les instantanés Scala 2.8. Il semble donc que TwiP ne fonctionnera pas du tout, sauf si vous mettez à niveau Scala ou si vous trouvez un moyen de faire fonctionner TwiP avec des méthodes de génération de paramètres non statiques.

2

Il suffit de définir la variable comme "val" dans un objet compagnon.

object Foo{ 
    val MyStrings = Array("A","B","C") 
} 

REMARQUE: les variables statiques finales dans scala ne suivent pas la même convention qu'en Java. Jetez un oeil à: http://docs.scala-lang.org/style/naming-conventions.html

Questions connexes