2011-03-22 20 views
39

Este es mi código.¿Admite Java métodos internos/locales/secundarios?

public class SubFunction { 
    private String drawTribleX(){ 
     return trible("X"); 
    } 
    private String trible(String t){ 
     return t + t + t; 
    } 
    public static void main(String[] args){ 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 
} 

¿Puedo hacer algo como esto?

public class SubFunction { 
    private String drawTribleX(){ 
     // *** move trible(t) inside drawTribleX() *** 
     private String trible(String t){ 
      return t + t + t; 
     } 
     return trible("X"); 
    } 
    public static void main(String[] args){ 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 
} 

Gracias.

+4

Si hubiera tipeado su ejemplo en un IDE, su compilador ya le habría dicho la respuesta. – Bombe

+0

Posible duplicado de [Funciones anidadas en Java] (http://stackoverflow.com/questions/7367714/nested-functions-in-java) –

+4

@Bombe, en realidad no. Un IDE podría haber determinado si OP podría hacer * exactamente * eso. Si lees con cuidado, habrás notado que la pregunta era "¿Puedo hacer * algo así como * esto?" – aioobe

Respuesta

93

Actualización 02/09/2014:

JDK 8 lambdas introducidas (expresiones de funciones anónimas) que le permiten resolver de esta manera:

Function<String, String> trible = s -> s+s+s; 
System.out.println(trible.apply("X"));   // prints XXX 

(JDK 7 y siguientes)

No, Java lo hace no es compatible con los métodos anidados "directamente". (Sin embargo, la mayoría de los lenguajes funcionales lo hacen, incluidos algunos lenguajes JVM como Scala y Clojure).

Solo como referencia; Usted puede definir clases locales (clases dentro de los métodos) así que esto lo hace compilar

class SubFunction { 
    private String drawTribleX(){ 

     // *** move trible(t) inside drawTribleX() *** 
     class Trible { 
      private String trible(String t){ 
       return t + t + t; 
      } 
     } 

     return new Trible().trible("X"); 
    } 
    public static void main(String[] args){ 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 
} 

en cuenta sin embargo que hay algunos restrictions on local classes

3.11.2. Restricciones en clases locales

clases locales están sujetos a las siguientes restricciones:

  • una clase local sólo es visible dentro del bloque que lo define; nunca puede usarse fuera de ese bloque.

  • Las clases locales no se pueden declarar como públicas, protegidas, privadas o estáticas. Estos modificadores son para miembros de clases; no están permitidos con declaraciones de variables locales o declaraciones de clases locales.

  • Al igual que las clases de miembro, y por las mismas razones, las clases locales no pueden contener campos estáticos, métodos o clases. La única excepción es para las constantes que se declaran tanto estáticas como finales.

  • Las interfaces no se pueden definir localmente.

  • Una clase local, como una clase miembro, no puede tener el mismo nombre que cualquiera de sus clases adjuntas.

  • Como se indicó anteriormente, una clase local puede usar las variables locales, los parámetros del método e incluso los parámetros de excepción que están en su alcance, pero solo si esas variables o parámetros se declaran definitivos. Esto se debe a que la duración de una instancia de una clase local puede ser mucho más larga que la ejecución del método en el que se define la clase. Por esta razón, una clase local debe tener una copia interna privada de todas las variables locales que utiliza (estas copias son generadas automáticamente por el compilador).La única forma de garantizar que la variable local y la copia privada sean siempre iguales es insistir en que la variable local es definitiva.

tanto, como se puede ver, su primera opción (sin métodos anidados) es preferible en estas situaciones.

+11

Major +1 para mantener esta respuesta actualizada. –

+0

¿Puede el método 'trible' dentro de la clase' Trible' ser 'estático'? Esto evitará tener que crear un objeto 'new Trible()' como podría llamar al método estático: 'Trible.trible (" X ")'. En una nota relacionada, ¿puede la clase 'Trible' ser' estática'? ¿Ofrecerá eso alguna ventaja? – ADTC

+1

No. Está en la segunda viñeta en 3.11.2. – aioobe

6

Bastante simple - no. No puedes anidar un método dentro de otro método.

Si realmente quiere hacer esto, puede definir clases dentro de los métodos (Curiosamente, dada la restricción anterior) y así podría envolver sus métodos dentro de una clase dentro del método exterior.

Sin embargo, esto no es muy idiomático, y la práctica general parece ser tener una lista de métodos privados (en la clase de nivel superior), tal vez agrupados según el propósito y con bloques de comentarios que demarcan los grupos.


Si por casualidad te encuentras usando Scala, sin embargo, puede distancia al contenido de su corazón métodos nido ...

1

se puede tratar de esta manera, así que es de clase interna anónima.

public class SubFunction { 
    private String drawTribleX() { 
     // *** move trible(t) inside drawTribleX() *** 
     Trible t = new Trible() { 
      public String trible(String t) { 
       return t + t + t; 
      } 
     }; 
     return t.trible("X"); 
    } 

    public static void main(String[] args) { 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 

    interface Trible { 
     String trible(String t); 
    } 
} 
0

Puede utilizar una clase anónima. Algo como esto;

class SubFunction { 

    public static void main(String[] args) { 
     SubFunction o = new SubFunction(); 
     System.out.println(o.drawTribleX()); 
    } 

    private String drawTribleX() { 
     MyTrible trible = new MyTrible() { 
      @Override 
      public String doTrible(String t) { 
       return t + t + t; 
      } 
     }; 

     return trible.doTrible("X"); 
    } 

    private interface MyTrible { 
     public String doTrible(String t); 
    } 
} 

Si lo desea, podría definir diferentes tipos de operaciones con la misma interfaz y pasarlas como desee.