1.内部类
1 package innerClass; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.util.*; 6 import javax.swing.*; 7 import javax.swing.Timer; 8 9 /**10 * This program demonstrates the use of inner classes.11 * @version 1.11 2015-05-1212 * @author Cay Horstmann13 */14 public class InnerClassTest15 {16 public static void main(String[] args)17 {18 TalkingClock clock = new TalkingClock(1000, true);19 clock.start();20 21 // keep program running until user selects "Ok"22 JOptionPane.showMessageDialog(null, "Quit program?");23 System.exit(0);24 }25 }26 27 /**28 * A clock that prints the time in regular intervals.29 */30 class TalkingClock31 {32 private int interval;33 private boolean beep;34 35 /**36 * Constructs a talking clock37 * @param interval the interval between messages (in milliseconds)38 * @param beep true if the clock should beep39 */40 public TalkingClock(int interval, boolean beep)41 {42 this.interval = interval;43 this.beep = beep;44 }45 46 /**47 * Starts the clock.48 */49 public void start()50 {51 ActionListener listener = new TimePrinter();52 Timer t = new Timer(interval, listener);53 t.start();54 }55 56 public class TimePrinter implements ActionListener57 {58 public void actionPerformed(ActionEvent event)59 {60 System.out.println("At the tone, the time is " + new Date());61 if (beep) Toolkit.getDefaultToolkit().beep();62 }63 }64 }
2.匿名内部类
1 package anonymousInnerClass; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.util.*; 6 import javax.swing.*; 7 import javax.swing.Timer; 8 9 /**10 * This program demonstrates anonymous inner classes.11 * @version 1.11 2015-05-1212 * @author Cay Horstmann13 */14 public class AnonymousInnerClassTest15 {16 public static void main(String[] args)17 {18 TalkingClock clock = new TalkingClock();19 clock.start(1000, true);20 21 // keep program running until user selects "Ok"22 JOptionPane.showMessageDialog(null, "Quit program?");23 System.exit(0);24 }25 }26 27 /**28 * A clock that prints the time in regular intervals.29 */30 class TalkingClock31 {32 /**33 * Starts the clock.34 * @param interval the interval between messages (in milliseconds)35 * @param beep true if the clock should beep36 */37 public void start(int interval, boolean beep)38 {39 ActionListener listener = new ActionListener()40 {41 public void actionPerformed(ActionEvent event)42 {43 System.out.println("At the tone, the time is " + new Date());44 if (beep) Toolkit.getDefaultToolkit().beep();45 }46 };47 Timer t = new Timer(interval, listener);48 t.start();49 }50 }
第二种方法比第一种更为简洁,多年来,Java程序员习惯的做法是用匿名内部类实现事件监听器和其他回调。
上述两种方法可以用lambda来实现,更为简洁
1 public void start(int interval, boolean beep) {2 Timer t = new Timer(interval, event -> {3 System.out.println("At the tone, the time is " + new Date());4 if (beep) Toolkit.getDefaultToolkit().beep();5 });6 t.start();7 }
3.匿名内部类的一个使用技巧--“双括号初始化”
假设你想构造一个数组列表,并将它传递到一个方法:
1 ArrayListfriends = new ArrayList<>();2 friends.add("Harry");3 friends.add("Tony");4 invite(friends);
如果不在需要这个数组列表,最好让他作为一个匿名列表,方法如下:
invite(new ArrayList() { { add("Harrry"); add("Tony"); }});
外层括号建立了ArrayList的一个匿名子类,内层括号则是一个对象构造块。
4.静态内部类
1 package staticInnerClass; 2 3 /** 4 * This program demonstrates the use of static inner classes. 5 * @version 1.02 2015-05-12 6 * @author Cay Horstmann 7 */ 8 public class StaticInnerClassTest 9 {10 public static void main(String[] args)11 {12 double[] d = new double[20];13 for (int i = 0; i < d.length; i++)14 d[i] = 100 * Math.random();15 ArrayAlg.Pair p = ArrayAlg.minmax(d);16 System.out.println("min = " + p.getFirst());17 System.out.println("max = " + p.getSecond());18 }19 }20 21 class ArrayAlg22 {23 /**24 * A pair of floating-point numbers25 */26 public static class Pair27 {28 private double first;29 private double second;30 31 /**32 * Constructs a pair from two floating-point numbers33 * @param f the first number34 * @param s the second number35 */36 public Pair(double f, double s)37 {38 first = f;39 second = s;40 }41 42 /**43 * Returns the first number of the pair44 * @return the first number45 */46 public double getFirst()47 {48 return first;49 }50 51 /**52 * Returns the second number of the pair53 * @return the second number54 */55 public double getSecond()56 {57 return second;58 }59 }60 61 /**62 * Computes both the minimum and the maximum of an array63 * @param values an array of floating-point numbers64 * @return a pair whose first element is the minimum and whose second element65 * is the maximum66 */67 public static Pair minmax(double[] values)68 {69 double min = Double.POSITIVE_INFINITY;70 double max = Double.NEGATIVE_INFINITY;71 for (double v : values)72 {73 if (min > v) min = v;74 if (max < v) max = v;75 }76 return new Pair(min, max);77 }78 }
优点:1.避免编写两个函数,一个计算最小值,一个计算最大值,只需要遍历一次就可以了。
2.Pair是一个十分大众化的名字,其他程序员很有可能会使用这个名字,这样就会产生名字冲突,解决这个问题的办法是将Pair定义为ArrayAlg的内部公有类,通过ArrayAlg.Pair来访问它。