2010-01-11 13 views
12

Tengo un problema al usar constructores con una clase Groovy.Constructores Groovy

Tengo una clase Data en un archivo llamado Data.groovy con una clase interna ContentEntry. Quiero inicializar ContentEntry instancias de un método Data:

static void initContent(nid, uid) 
{ 
    curContent = new ContentEntry() 
    curContent.nid = nid; 
    curContent.uid = uid; 
} 

con ContentEntry define como:

class ContentEntry 
{ 
    public int nid, uid 
    private tags = [:] 

    public ContentEntry() 
    { 

    } 

    ContentEntry(int nid, int uid) 
    { 
     this.nid = nid 
     this.uid = uid 
    } 

    //omitted rest of the class 

Pero cuando se ejecuta el proyecto me da el siguiente error:

Exception in thread "main" org.codehaus.groovy.runtime.metaclass.MethodSelectionException: 
Could not find which method <init>() to invoke from this list: 
public it.softit.Data$ContentEntry#<init>(it.softit.Data, int, int) 
public it.softit.Data$ContentEntry#<init>(it.softit.Data) 

¡Es como si los constructores implícitamente necesitaran una instancia de la clase externa pasada como parámetro. Me pregunto por qué ...

+0

3 food anwers thanks, upvoted all you you .. En 6 años de programación en Java nunca se supo esto de la referencia implícita. Lo solucioné declarándolos como clases normales ya que no puedes declararlos estáticos en groovy. – Jack

Respuesta

9

El requisito de que todas las clases internas (no estáticas) necesiten una referencia a su clase externa es impuesto por Java, en lugar de por Groovy. Si crea una instancia de la clase interna a partir de un método no estático, la referencia debe establecerse en this. Sin embargo, no hay referencia this dentro de un método estático.

Para solucionar el problema o bien:

  • una instancia de la clase interna de un método no estático
  • Hacer la clase interna estática. Luego puede instanciarlo desde cualquier lugar (pero ya no tendrá una referencia a una instancia de la clase externa).
4

Por supuesto, el constructor necesita una instancia de la clase externa. Es por eso que existe la clase interna: vivir solo dentro de una clase externa. No puedes instanciar una clase interna fuera de su clase externa.

+0

Es importante tener en cuenta que Java y Groovy actúan de manera diferente aquí: en Java, la instancia de la clase externa se pasa implícitamente, mientras que en Groovy se necesita pasarla como un argumento explícito. –

+0

Para agregar a lo que dice el gizmo, hacer que la clase de contenido sea "estática" podría ser útil también. –

+0

@Joachim: cuando trato de hacer eso, me dice: no hay tal constructor (¿no se ha corregido esto en 1.7.1?) – Matthias

2

En Java sucede lo mismo, pero cuando crea una instancia interna no tiene que incluir el parámetro oculto.

probar una de dos cosas:

  1. declarar la clase interna estática (I espero que puede hacer que en Groovy también)
  2. pasar this en la creación de la ContentEntry ejemplo ...:)