Java Tutorial/Class Definition/Anonymous inner class

Материал из Java эксперт
Перейти к: навигация, поиск

Accessing its enclosing instance from an inner class

public class Main {
  private int number = 12;
  public Main() {
    InnerClass inner = new InnerClass();
    inner.printNumber();
  }
  class InnerClass {
    public void printNumber() {
      System.out.println(Main.this.number);
    }
  }
  public static void main(String[] args) {
    new Main();
  }
}





Access inner class from outside

public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.new Inner().hello();
    }
}
class Outer {
    public class Inner {
        public void hello(){
          System.out.println("Hello from Inner()");
        }
    }
}





A method that returns an anonymous inner class

public class MainClass {
  public A cont() {
    return new A() {
      private int i = 11;
      public int value() {
        return i;
      }
    }; // Semicolon required in this case
  }
  public static void main(String[] args) {
    MainClass p = new MainClass();
    A c = p.cont();
  }
}
interface A {
  int value();
}





An anonymous inner class that calls the base-class constructor

public class MainClass {
  public A wrap(int x) {
    // Base constructor call:
    return new A(x) { // Pass constructor argument.
      public int value() {
        return super.value() * 47;
      }
    }; // Semicolon required
  }
  public static void main(String[] args) {
    MainClass p = new MainClass();
    A w = p.wrap(10);
  }
}
class A {
  private int i;
  public A(int x) {
    i = x;
  }
  public int value() {
    return i;
  }
}





An anonymous inner class that performs initialization

public class MainClass {
  public A dest(final String dest) {
    return new A() {
      private String label = dest;
      public String readLabel() {
        return label;
      }
    };
  }
  public static void main(String[] args) {
    MainClass p = new MainClass();
    A d = p.dest("A");
  }
}
interface A {
  String readLabel();
}





Anonymous inner class cannot have a named constructor, only an instance initializer

interface Counter {
  int next();
}
public class MainClass{
  
  private int count = 0;
  Counter getCounter(final String name) {
    return new Counter() {
      
      {
        System.out.println("Counter()");
      }
      public int next() {
        System.out.print(name); // Access local final
        return count++;
      }
    };
  }
  
  public static void main(String[] args) {
    MainClass lic = new MainClass();
    Counter c1 = lic.getCounter("Local inner ");
  }
}





Argument must be final to use inside anonymous inner class

public class MainClass {
  public A dest(final String dest) {
    return new A() {
      private String label = dest;
      public String readLabel() {
        return label;
      }
    };
  }
  public static void main(String[] args) {
    MainClass p = new MainClass();
    A d = p.dest("A");
  }
}
interface A {
  String readLabel();
}





Building the anonymous inner class in-place

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;
public class MainClass {
  public static void main(final String[] args) {
    File path = new File(".");
    String[] list;
    if (args.length == 0)
      list = path.list();
    else
      list = path.list(new FilenameFilter() {
        private Pattern pattern = Pattern.rupile(args[0]);
        public boolean accept(File dir, String name) {
          return pattern.matcher(new File(name).getName()).matches();
        }
      });
    Arrays.sort(list);
    for (int i = 0; i < list.length; i++)
      System.out.println(list[i]);
  }
}





Creating a constructor for an anonymous inner class

abstract class Base {
  public Base(int i) {
    System.out.println("Base constructor, i = " + i);
  }
  public abstract void f();
}
public class MainClass {
  public static Base getBase(int i) {
    return new Base(i) {
      {
        System.out.println("Inside instance initializer");
      }
      public void f() {
        System.out.println("In anonymous f()");
      }
    };
  }
  public static void main(String[] args) {
    Base base = getBase(47);
    base.f();
  }
}



Base constructor, i = 47
Inside instance initializer
In anonymous f()


Define an inner class within a for loop.

class Outer {
  int outer_x = 100;
   
  void test() {
    for(int i=0; i<10; i++) {
      class Inner {
        void display() {
          System.out.println("display: outer_x = " + outer_x);
        }
      }
      Inner inner = new Inner();
      inner.display();
    }
  }
}
   
class InnerClassDemo {
  public static void main(String args[]) {
    Outer outer = new Outer();
    outer.test();
  }
}





Demonstrate an inner class.

class Outer {
  int outer_x = 100;
   
  void test() {
    Inner inner = new Inner();
    inner.display();
  }
   
  // this is an inner class
  class Inner {
    void display() {
      System.out.println("display: outer_x = " + outer_x);
    }
  }
}
   
class InnerClassDemo {
  public static void main(String args[]) {
    Outer outer = new Outer();
    outer.test();
  }
}





Demonstrates anonymous classes

/*
 *     file: InnerClassDemo.java
 *  package: oreilly.hcj.nested
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
 ########## DO NOT EDIT ABOVE THIS LINE ########## */
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
/**
 * Demonstrates anonymous classes.
 * 
 * @author 
   * @version $Revision: 1.3 $
   */
  private class BeepButton extends JButton implements ActionListener {
    /**
     * Creates a new BeepButton object.
     * 
     * @param text
     *          The text to use for the beep button.
     */
    public BeepButton(final String text) {
      super(text);
      addActionListener(this);
    }
    /**
     * @see java.awt.event.ActionListener
     */
    public void actionPerformed(final ActionEvent event) {
      try {
        for (int count = 0; count < beepCount; count++) {
          Toolkit.getDefaultToolkit().beep();
          Thread.sleep(100); // wait for the old beep to finish.
        }
      } catch (final InterruptedException ex) {
        throw new RuntimeException(ex);
      }
    }
  }
}
/* ########## End of File ########## */





Demonstrates method-scoped inner classes

/*
 *     file: MethodInnerClassDemo.java
 *  package: oreilly.hcj.nested
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
 ########## DO NOT EDIT ABOVE THIS LINE ########## */
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
 * Demonstrates method-scoped inner classes.
 * 
 * @author 
     * @version $Revision: 1.6 $
     */
    class MyActionListener implements ActionListener {
      /**
       * {@inheritDoc}
       */
      public void actionPerformed(final ActionEvent event) {
        Toolkit.getDefaultToolkit().beep();
      }
    }
    btn1.addActionListener(new MyActionListener());
    btn2.addActionListener(new MyActionListener());
    JPanel pnl = new JPanel(new GridLayout(1, 2));
    pnl.add(btn1);
    pnl.add(btn2);
    contentPane.add(BorderLayout.SOUTH, pnl);
    pack();
  }
  /**
   * Run the demo
   * 
   * @param args
   *          Command Line Arguments.
   */
  public static final void main(final String[] args) {
    MethodInnerClassDemo demo = new MethodInnerClassDemo();
    demo.show();
    System.out.println("Done");
  }
  /**
   * Setter for the property demo.
   * 
   * @param demo
   *          The new value for demo.
   */
  public void setDemo(final String demo) {
    this.demo = demo;
  }
  /**
   * Getter for the property demo.
   * 
   * @return The current value of demo.
   */
  public String getDemo() {
    return demo;
  }
  /**
   * Some demo method.
   */
  public void someMethod() {
    // ActionListener listener = new MyActionListener(); // <= compiler error.
  }
}
/* ########## End of File ########## */





Demonstration of some static nested classes

/*
 *     file: DoubleNestedClassDemo.java
 *  package: oreilly.hcj.nested
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */
/*
 *     file: DoubleNestedClass.java
 *  package: oreilly.hcj.nested
 *
 * This software is granted under the terms of the Common Public License,
 * CPL, which may be found at the following URL:
 * http://www-124.ibm.ru/developerworks/oss/CPLv1.0.htm
 *
 * Copyright(c) 2003-2005 by the authors indicated in the @author tags.
 * All Rights are Reserved by the various authors.
 *
########## DO NOT EDIT ABOVE THIS LINE ########## */

/**  
 * Demonstration of some static nested classes.
 *
 * @author 
 * @version $Revision: 1.3 $
 */
public class DoubleNestedClassDemo {
  /** 
   * Main method.
   *
   * @param args Command line arguments.
   */
  public static void main(final String[] args) {
    DoubleNestedClass.SomeClass.SomeOtherClass obj =
      new DoubleNestedClass.SomeClass.SomeOtherClass();
    obj.someMethod();
  }
}
/* ########## End of File ########## */





Use anonymous inner classes

import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.regex.Pattern;
public class MainClass {
  public static FilenameFilter filter(final String regex) {
    // Creation of anonymous inner class:
    return new FilenameFilter() {
      private Pattern pattern = Pattern.rupile(regex);
      public boolean accept(File dir, String name) {
        return pattern.matcher(new File(name).getName()).matches();
      }
    }; // End of anonymous inner class
  }
  public static void main(String[] args) {
    File path = new File(".");
    String[] list;
    if (args.length == 0)
      list = path.list();
    else
      list = path.list(filter(args[0]));
    Arrays.sort(list);
    for (int i = 0; i < list.length; i++)
      System.out.println(list[i]);
  }
}





Using "instance initialization" to perform construction on an anonymous inner class

public class MainClass {
  public A dest(final String dest, final float price) {
    return new A() {
      private int cost;
      {
        cost = 100;
        System.out.println("Over budget!");
      }
      private String label = dest;
      public String readLabel() {
        return label;
      }
    };
  }
  public static void main(String[] args) {
    MainClass p = new MainClass();
    A d = p.dest("A", 101.395F);
  }
}
interface A {
  String readLabel();
}