2013-10-22 10 views
7

leggevo il libro "Head First Java" e ad un certo punto si segnala che un'istanza classe interna deve essere legato a un'istanza classe esterna, che ero già a conoscenza, ma con un'eccezione:Qual è lo scopo di definire una classe interna all'interno di un metodo statico?

Un caso speciale- una classe interna definita all'interno di un metodo statico. Ma potresti passare la tua intera vita Java senza mai incontrare uno di questi .

Sono sicuro che l'ultima affermazione è vera, ma se il compilatore consente che accada, significa che esiste per una ragione, altrimenti sarebbe illegale Java. Qualcuno può mostrarmi un esempio di dove sarebbe utile?

+3

Può essere una classe interna anonima? Perché ce ne sono tantissime. –

+0

Questa è una classe locale, [JLS # 14.3] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.3), non solo una classe interiore. – EJP

+0

@EJP Ma è * una * classe interiore, quindi soddisfa i criteri della domanda. –

risposta

3

Potrebbe essere speciale, potrebbe non esserlo.

Stai guardando una classe locale a disposizione all'interno di un metodo: usi

class Foo { 
    static void bar(){ 
     class MyRunnable implements Runnable { 
      public void run() { 
       System.out.println("No longer anonymous!"); 
      }  
     }; 
     Thread baz = new Thread(new MyRunnable()); 
    } 

} 

che ho visto di classi interne che sono come anonimo:

class Foo { 
    static void bar(){ 
     Thread baz=new Thread(new Runnable(){ 
      public void run(){ 
       System.out.println("quux"); 
      } 
     } 
    } 
} 

Questo è tecnicamente una classe interna (anche se anonimo) e definito in un metodo statico. Personalmente mi creare una classe innestata statica che implementa Runnable e fare:

baz = new Thread(new MyRunnable()); 

dove MyRunnable è definito come:

class Foo { 
    static void bar(){ 
     // SNIP 
    } 
    static class MyRunnable implements Runnable { 
     public void run() { 
      System.out.println("No longer anonymous!"); 
     }  
    } 
} 
+1

Se si sposta 'MyRunnable' all'interno di' bar' si ha lo stesso identico scenario in cui è interessato fedeetz. –

+0

@MiserableVariable Aggiornato per il primo blocco di codice. – hexafraction

+0

Non verrà compilato, cambierà 'classe statica MyRunnable' in' classe MyRunnable' –

1

Alcune persone sono del parere che qualsiasi metodo che può essere statico dovrebbe essere statico. Per una persona del genere, la bellezza interiore della classe non sarebbe terribilmente rilevante.

0

Non conosco il contesto completo, ma le chiusure (ad esempio l'implementazione Function di Guava) e le implementazioni definite in una classe di utilità potrebbero essere un esempio.

Tuttavia, dopo aver cercato per un po ', non ho trovato esempi di chiusura anonimi in Guava stessa.

1

Ecco un esempio fabbricato di una classe interna all'interno di un metodo statico. Si può affermare che

  1. E non ha bisogno di essere dichiarato fuori del metodo statico in quanto non è richiesto altrove
  2. Dovrebbe essere una classe denominata (cioè non anonimo) come viene utilizzato più volte

    class Race { 
        public static void main(String[] args) throws Exception{ 
         class Runner implements Runnable { 
          final String name; 
          long time = -1; 
          Runner(String name) { this.name = name; } 
          public void run() { 
           try { 
            long start = System.currentTimeMillis(); 
            time = -2; 
            System.out.printf("Start %s\n", name); 
            for (int i = 0; i < 10; i++) { 
             Thread.sleep(1000); 
            } 
            System.out.printf("End %s\n", name); 
            this.time = System.currentTimeMillis() - start; 
           } catch (InterruptedException e) { 
            time = -3; 
           } 
          } 
          long time() { return time; } 
         }     
         Runner r1 = new Runner("One"); 
         Runner r2 = new Runner("Two"); 
         Thread one = new Thread(r1); 
         Thread two = new Thread(r2); 
         one.start(); 
         two.start(); 
         one.join(); 
         two.join(); 
         System.out.printf("One: %s, Two: %s\n", r1.time(), r2.time()); 
         System.out.printf("%s wins\n", r1.time() < r2.time() ? "one" : "two"); 
        } 
    } 
    
+0

Grazie per l'esempio! – federicot

Problemi correlati