java 内部类
来源:互联网 发布:奔驰配件查询软件 编辑:程序博客网 时间:2024/05/16 16:22
内部类
我觉得这个源代码对理解匿名内部类有很好的帮助,
原来的代码标号是001,后面的都是我自己改的,我都试过了都可以运行,
我已经试着尽量描述的清楚些,可是涉及的方面太多,
我只能捡重要的说,如果有看不懂的话可以再问
可以在自己机器上先运行一下,注意如果放在包里,前面要加包的名称
整个的代码是
//001
// ExceptTest
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class ExceptTest
{
public static void main(String[] args)
{
ExceptTestFrame frame = new ExceptTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
/**
A frame with a panel for testing various exceptions
*/
class ExceptTestFrame extends JFrame
{
public ExceptTestFrame()
{
setTitle("ExceptTest");
Container contentPane = getContentPane();
ExceptTestPanel panel = new ExceptTestPanel();
contentPane.add(panel);
pack();
}
}
/**
A panel with radio buttons for running code snippets
and studying their exception behavior
*/
class ExceptTestPanel extends Box
{
public ExceptTestPanel()
{
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
// add radio buttons for code snippets
addRadioButton("Integer divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1 / (a.length - a.length);
}
});
addRadioButton("Floating point divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = a[2] / (a[3] - a[3]);
}
});
addRadioButton("Array bounds", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = a[10];
}
});
addRadioButton("Bad cast", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a = (double[])event.getSource();
}
});
addRadioButton("Null pointer", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
event = null;
System.out.println(event.getSource());
}
});
addRadioButton("sqrt(-1)", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = Math.sqrt(-1);
}
});
addRadioButton("Overflow", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1000 * 1000 * 1000 * 1000;
int n = (int)a[1];
}
});
addRadioButton("No such file", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
try
{
FileInputStream is
= new FileInputStream("No such file");
}
catch (IOException exception)
{
textField.setText(exception.toString());
}
}
});
addRadioButton("Throw unknown", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
throw new UnknownError();
}
});
// add the text field for exception display
textField = new JTextField(30);
add(textField);
}
/**
Adds a radio button with a given listener to the
panel. Traps any exceptions in the actionPerformed
method of the listener.
@param s the label of the radio button
@param listener the action listener for the radio button
*/
private void addRadioButton(String s, ActionListener listener)
{
JRadioButton button = new JRadioButton(s, false)
{
// the button calls this method to fire an
// action event. We override it to trap exceptions
protected void fireActionPerformed(ActionEvent event)
{
try
{
super.fireActionPerformed(event);
textField.setText("No exception");
}
catch (Exception exception)
{
textField.setText(exception.toString());
}
}
};
button.addActionListener(listener);
add(button);
group.add(button);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
}
我简化了一下
//002
//ExceptTest
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class ExceptTest
{
public static void main(String[] args)
{
ExceptTestFrame frame = new ExceptTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
class ExceptTestFrame extends JFrame
{
public ExceptTestFrame()
{
setTitle("ExceptTest");
Container contentPane = getContentPane();
ExceptTestPanel panel = new ExceptTestPanel();
contentPane.add(panel);
pack();
}
}
class ExceptTestPanel extends Box
{
public ExceptTestPanel()
{
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
addRadioButton("Integer divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1 / (a.length - a.length);
}
}
);
// add the text field for exception display
textField = new JTextField(30);
add(textField);
}
private void addRadioButton(String s, ActionListener listener)
{
JRadioButton button = new JRadioButton(s, false)
{
protected void fireActionPerformed(ActionEvent event)
{
try
{
super.fireActionPerformed(event);
textField.setText("No exception");
}
catch (Exception exception)
{
textField.setText(exception.toString());
}
}
};
button.addActionListener(listener);
add(button);
group.add(button);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
}
前面的几个都是gui的惯例,只要不出错,就不用去管它,
先看这个ExceptTestPanel 类里的私有函数
private void addRadioButton(String s, ActionListener listener),
其实如果只要加一个圆形的互斥按钮的话,
就完全不需要这个私有函数,你可以简单的这莫写这个ExceptTestPanel类,
可以用这个代替原来的,然后运行一下,结果是一样的,
class ExceptTestPanel extends Box implements ActionListener {
public ExceptTestPanel() {
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
JRadioButton button = new JRadioButton("Integer divide by zero", false) {
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
textField.setText("No exception");
} catch (Exception exception) {
textField.setText(exception.toString());
}
}
};
button.addActionListener(this);
add(button);
group.add(button);
textField = new JTextField(30);
add(textField);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
public void actionPerformed(ActionEvent arg0) {
a[1] = 1 / (a.length - a.length);
}
}
但是你既然用了ButtonGroup就肯定不止一个按钮了,所以如果再这样加上第二个按钮这个类就变成了下面这样了,
你可以先替换一下原来的类,再运行一下,
class ExceptTestPanel extends Box implements ActionListener {
public ExceptTestPanel() {
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
JRadioButton button = new JRadioButton("Integer divide by zero", false) {
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
textField.setText("No exception");
} catch (Exception exception) {
textField.setText(exception.toString());
}
}
};
button.addActionListener(this);
add(button);
group.add(button);
JRadioButton button2 = new JRadioButton("Array bounds", false) {
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
textField.setText("No exception");
} catch (Exception exception) {
textField.setText(exception.toString());
}
}
};
button2.addActionListener(this);
add(button2);
group.add(button2);
textField = new JTextField(30);
add(textField);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
public void actionPerformed(ActionEvent e) {
String s;
s = e.getActionCommand();
if (s == "Integer divide by zero") {
a[1] = 1 / (a.length - a.length);
} else if (s == "Array bounds") {
a[1] = a[10];
}
}
}
因为,ExceptTestPanel 这个类实现了事件监听 ActionListener 这个接口,
但是如果你加上2个以上的按钮的话,必须在 actionPerformed 里区分这个送过来的事件对象,
因为你在按钮上注册的都是this, 如果我们用一个类C实现了ActionListener 这个接口,
你就可以在按钮上加上这个C类的实例,但是这莫做会使代码变得重复而且复杂不容易发现错误,
而且要定义 JRadioButton 的实例名称,如果用button2,button3,这莫命名,不但不好,
而且容易出错,并且我们基本上用不到JRadioButton 的实例名称
然后现在再回来看简化的版本002, 它把重复用到的这些方法放在一个私有函数里面,把里面的方法需要的变量用
参数给传进去,这个就是匿名内部类,
JRadioButton button = new JRadioButton(s, false)
{
protected void fireActionPerformed(ActionEvent event)
{
try
{
super.fireActionPerformed(event);
textField.setText("No exception");
}
catch (Exception exception)
{
textField.setText(exception.toString());
}
}
};
然后,调用这个函数的时候,用的也是一个匿名内部类,因为这个私有函数的参数是一个ActionListener 事件监听接口,
接口如果没有被一个类实现,是不能有实例的,也就是说接口不能被实例化,也就是不能用new ActionListener() 这种写法,
但是匿名内部类是唯一可以这莫用的,因为匿名内部类也是没有名字的,new ActionListener() 这莫写,
意思就是 内部类实现该接口,
addRadioButton("Integer divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1 / (a.length - a.length);
}
}
);
按钮是一个主题, ActionListener 是观察者,即使是代码的结构变了,这个还是不变的,
fireActionPerformed 其实就是 主题里的 Notify, 就是通知ActionListener的实现者,
按钮被按下了,然后把事件对象给送过去,ActionListener的实现者接到这个事件对象然后
事件被执行,如果在事件执行时有异常,就捕获异常然后把异常的描述放在textField里,
如果事件执行时没有异常,就把继续执行下个语句 把No exception 放在textField里。
我觉得这个源代码对理解匿名内部类有很好的帮助,
原来的代码标号是001,后面的都是我自己改的,我都试过了都可以运行,
我已经试着尽量描述的清楚些,可是涉及的方面太多,
我只能捡重要的说,如果有看不懂的话可以再问
可以在自己机器上先运行一下,注意如果放在包里,前面要加包的名称
整个的代码是
//001
// ExceptTest
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class ExceptTest
{
public static void main(String[] args)
{
ExceptTestFrame frame = new ExceptTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
/**
A frame with a panel for testing various exceptions
*/
class ExceptTestFrame extends JFrame
{
public ExceptTestFrame()
{
setTitle("ExceptTest");
Container contentPane = getContentPane();
ExceptTestPanel panel = new ExceptTestPanel();
contentPane.add(panel);
pack();
}
}
/**
A panel with radio buttons for running code snippets
and studying their exception behavior
*/
class ExceptTestPanel extends Box
{
public ExceptTestPanel()
{
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
// add radio buttons for code snippets
addRadioButton("Integer divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1 / (a.length - a.length);
}
});
addRadioButton("Floating point divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = a[2] / (a[3] - a[3]);
}
});
addRadioButton("Array bounds", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = a[10];
}
});
addRadioButton("Bad cast", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a = (double[])event.getSource();
}
});
addRadioButton("Null pointer", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
event = null;
System.out.println(event.getSource());
}
});
addRadioButton("sqrt(-1)", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = Math.sqrt(-1);
}
});
addRadioButton("Overflow", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1000 * 1000 * 1000 * 1000;
int n = (int)a[1];
}
});
addRadioButton("No such file", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
try
{
FileInputStream is
= new FileInputStream("No such file");
}
catch (IOException exception)
{
textField.setText(exception.toString());
}
}
});
addRadioButton("Throw unknown", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
throw new UnknownError();
}
});
// add the text field for exception display
textField = new JTextField(30);
add(textField);
}
/**
Adds a radio button with a given listener to the
panel. Traps any exceptions in the actionPerformed
method of the listener.
@param s the label of the radio button
@param listener the action listener for the radio button
*/
private void addRadioButton(String s, ActionListener listener)
{
JRadioButton button = new JRadioButton(s, false)
{
// the button calls this method to fire an
// action event. We override it to trap exceptions
protected void fireActionPerformed(ActionEvent event)
{
try
{
super.fireActionPerformed(event);
textField.setText("No exception");
}
catch (Exception exception)
{
textField.setText(exception.toString());
}
}
};
button.addActionListener(listener);
add(button);
group.add(button);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
}
我简化了一下
//002
//ExceptTest
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
public class ExceptTest
{
public static void main(String[] args)
{
ExceptTestFrame frame = new ExceptTestFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
class ExceptTestFrame extends JFrame
{
public ExceptTestFrame()
{
setTitle("ExceptTest");
Container contentPane = getContentPane();
ExceptTestPanel panel = new ExceptTestPanel();
contentPane.add(panel);
pack();
}
}
class ExceptTestPanel extends Box
{
public ExceptTestPanel()
{
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
addRadioButton("Integer divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1 / (a.length - a.length);
}
}
);
// add the text field for exception display
textField = new JTextField(30);
add(textField);
}
private void addRadioButton(String s, ActionListener listener)
{
JRadioButton button = new JRadioButton(s, false)
{
protected void fireActionPerformed(ActionEvent event)
{
try
{
super.fireActionPerformed(event);
textField.setText("No exception");
}
catch (Exception exception)
{
textField.setText(exception.toString());
}
}
};
button.addActionListener(listener);
add(button);
group.add(button);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
}
前面的几个都是gui的惯例,只要不出错,就不用去管它,
先看这个ExceptTestPanel 类里的私有函数
private void addRadioButton(String s, ActionListener listener),
其实如果只要加一个圆形的互斥按钮的话,
就完全不需要这个私有函数,你可以简单的这莫写这个ExceptTestPanel类,
可以用这个代替原来的,然后运行一下,结果是一样的,
class ExceptTestPanel extends Box implements ActionListener {
public ExceptTestPanel() {
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
JRadioButton button = new JRadioButton("Integer divide by zero", false) {
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
textField.setText("No exception");
} catch (Exception exception) {
textField.setText(exception.toString());
}
}
};
button.addActionListener(this);
add(button);
group.add(button);
textField = new JTextField(30);
add(textField);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
public void actionPerformed(ActionEvent arg0) {
a[1] = 1 / (a.length - a.length);
}
}
但是你既然用了ButtonGroup就肯定不止一个按钮了,所以如果再这样加上第二个按钮这个类就变成了下面这样了,
你可以先替换一下原来的类,再运行一下,
class ExceptTestPanel extends Box implements ActionListener {
public ExceptTestPanel() {
super(BoxLayout.Y_AXIS);
group = new ButtonGroup();
JRadioButton button = new JRadioButton("Integer divide by zero", false) {
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
textField.setText("No exception");
} catch (Exception exception) {
textField.setText(exception.toString());
}
}
};
button.addActionListener(this);
add(button);
group.add(button);
JRadioButton button2 = new JRadioButton("Array bounds", false) {
protected void fireActionPerformed(ActionEvent event) {
try {
super.fireActionPerformed(event);
textField.setText("No exception");
} catch (Exception exception) {
textField.setText(exception.toString());
}
}
};
button2.addActionListener(this);
add(button2);
group.add(button2);
textField = new JTextField(30);
add(textField);
}
private ButtonGroup group;
private JTextField textField;
private double[] a = new double[10];
public void actionPerformed(ActionEvent e) {
String s;
s = e.getActionCommand();
if (s == "Integer divide by zero") {
a[1] = 1 / (a.length - a.length);
} else if (s == "Array bounds") {
a[1] = a[10];
}
}
}
因为,ExceptTestPanel 这个类实现了事件监听 ActionListener 这个接口,
但是如果你加上2个以上的按钮的话,必须在 actionPerformed 里区分这个送过来的事件对象,
因为你在按钮上注册的都是this, 如果我们用一个类C实现了ActionListener 这个接口,
你就可以在按钮上加上这个C类的实例,但是这莫做会使代码变得重复而且复杂不容易发现错误,
而且要定义 JRadioButton 的实例名称,如果用button2,button3,这莫命名,不但不好,
而且容易出错,并且我们基本上用不到JRadioButton 的实例名称
然后现在再回来看简化的版本002, 它把重复用到的这些方法放在一个私有函数里面,把里面的方法需要的变量用
参数给传进去,这个就是匿名内部类,
JRadioButton button = new JRadioButton(s, false)
{
protected void fireActionPerformed(ActionEvent event)
{
try
{
super.fireActionPerformed(event);
textField.setText("No exception");
}
catch (Exception exception)
{
textField.setText(exception.toString());
}
}
};
然后,调用这个函数的时候,用的也是一个匿名内部类,因为这个私有函数的参数是一个ActionListener 事件监听接口,
接口如果没有被一个类实现,是不能有实例的,也就是说接口不能被实例化,也就是不能用new ActionListener() 这种写法,
但是匿名内部类是唯一可以这莫用的,因为匿名内部类也是没有名字的,new ActionListener() 这莫写,
意思就是 内部类实现该接口,
addRadioButton("Integer divide by zero", new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
a[1] = 1 / (a.length - a.length);
}
}
);
按钮是一个主题, ActionListener 是观察者,即使是代码的结构变了,这个还是不变的,
fireActionPerformed 其实就是 主题里的 Notify, 就是通知ActionListener的实现者,
按钮被按下了,然后把事件对象给送过去,ActionListener的实现者接到这个事件对象然后
事件被执行,如果在事件执行时有异常,就捕获异常然后把异常的描述放在textField里,
如果事件执行时没有异常,就把继续执行下个语句 把No exception 放在textField里。
- 【Java】【内部类】Java 内部类简介
- [Java] Java 内部类
- Java 内部类(成员内部类、局部内部类、静态内部类和匿名内部类)
- Java内部类(成员内部类、静态内部类、局部内部类、匿名内部类)小结
- Java内部类(成员内部类、静态内部类、局部内部类、匿名内部类)小结
- Java内部类(成员内部类、局部内部类、静态内部类、匿名内部类)
- Java内部类(成员内部类、静态内部类、局部内部类、匿名内部类)小结
- Java内部类(成员内部类、静态内部类、局部内部类、匿名内部类)小结
- Java内部类(成员内部类、静态内部类、局部内部类、匿名内部类)小结
- java的内部类、匿名内部类、局部内部类
- java内部类之成员内部类、静态内部类
- java 成员内部类 局部内部类,匿名内部类
- Java 静态内部类/内部类
- java内部类、静态内部类 小结
- Java内部类,静态内部类
- JAVA 内部类与静态内部类
- java内部类--局部内部类
- Java 内部类以及匿名内部类
- C/C++语言void及void指针深层探索
- 关于动态加载程序集
- 想成为嵌入式程序员应知道的0x10个基本问题
- 关于分页的几种方案
- Lenovo Thinkpad X60安装MS-IIS
- java 内部类
- 设计模式
- eclipse
- Spring2.0正式发布了!
- 什么时候才会有对病毒免疫的操作系统么?
- NAT时将DNS转向内部自定义的DNS服务器(iptables 命令)
- 解决IIS中端口(如80)绑定到单个IP的问题
- C#读取键盘按键的程序
- 史上最恐怖FLASH游戏咒怨(附通关攻略)