1.java异常机制
Java异常(Exception)又称例外,是一种运行时错误。Java异常机制就是对于Java异常的处理方法,使用Java异常机制能提升程序的容错性,从而使程序更加健壮与安全。
异常的分类:
1.异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception.
2. Error和RuntimeException及其子类称为未检查异常(unchecked),其它异常称为已检查异常(checked)。
?
Error类描述了Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。
?
RuntimeException包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
?
JAVA中常见的几种异常:算术异常类(ArithmeticException),空指针异常类(NullPointerException),输入输出异常类(IOException),数组下标越界异常类(ArrayIndexOutOfBoundsException)、类型转换异常类(ClassCastException),数字格式异常(NumberFormatException)等。
?
Java中常有如下三种异常处理方法:
1.使用try-catch-finally语句。try语句块放置可能发生异常的代码,catch语句块捕获这些代码产生的异常,finally语句块无论程序是否有异常发生,都会执行。
2.使用throws关键字抛出异常。若某个方法可能发生异常,但不想在当前方法中处理这个异常,那就可以利用throws关键字在该方法抛出异常,然后在调用该方法的代码中捕获该异常进行处理。
3.自定义异常类与throw关键字
关于自定义异常类的使用,分为如下几个步骤:
1)创建自定义异常类,利用继承思想
2)在方法中通过throw关键字抛出异常对象
3)若在当前抛出异常的方法中处理,使用第一种方法,否则使用第二种方法。
**throw和throws的区别
区别一:
???????????? throw 是语句抛出一个异常;throws 是方法抛出一个异常;?
????????????? throw语法:throw <异常对象>?
????????????? 在方法声明中,添加throws子句表示该方法将抛出异常。?
???????????? throws语法:[<修饰符>]<返回值类型><方法名>([<参数列表>])[throws<异常类>]?
???????????? 其中:异常类可以声明多个,用逗号分割。?
区别二:
????????? throws可以单独使用,但throw不能;?
区别三:
??????????? throw要么和try-catch-finally语句配套使用,要么与throws配套使用。但throws可以单独使用,然后再由处理异常的方法捕获。??
throws E1,E2,E3 只是告诉程序这个方法可能会抛出这些个异常,方法的调用者可能要处理这些异常。而这些异常E1,E2,E3可能是该函数体产生的。 而throw是明确之处这个地方要抛出这个异常。 void doA() throws Exception1, Exception3 {?? try {???? ……
? } catch(Exception1 e) {???? throw e;
? } catch(Exception2 e) {
??? System.out.println("出错了");?? }
? if (a != b)
??? throw new Exception3("自定义异常"); }
2.实现五子棋进度的保存
感谢队友王小二的大力支持~~
保存进度,其实就是把我们所画的图形存到文件中。因此,我们需要一个文件打开和一个文件写入的方法,当然要实现保存,必须将保存与一个按钮,及其监听器相互绑定起来。
下面又是代码时间~~这次让我们先从主函数开始
class="java">import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseListener; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; public class Chesstry extends JPanel { String fileName = "F:/五子棋.txt"; Test test = new Test(); private int Longer; List<Chess> list = new ArrayList(); Graphics g; ChessListener cl; public static void main(String[] args) { // 实例化一个面板对象 Chesstry cb = new Chesstry(); cb.Beautiful(); } // 写一个设置棋盘的方法 public void Beautiful() { JFrame jf = new JFrame(); jf.setSize(600, 620); jf.setTitle("五子棋"); jf.setLocationRelativeTo(null); JPanel eastJpanel = new JPanel(); // 设置东边的布局的颜色 eastJpanel.setBackground(new Color(227, 160, 200)); // 设置东边的大小 eastJpanel.setPreferredSize(new Dimension(100, 0)); jf.add(eastJpanel, BorderLayout.EAST); // 在东边添加两个按钮 JButton jb1 = new JButton("开始"); JButton jb2 = new JButton("退出"); JButton jb3 = new JButton("黑子先手"); JButton jb4 = new JButton("白子先手"); JButton jb5 = new JButton("保存"); JButton jb6 = new JButton("打开"); // 将按钮加到面板上 eastJpanel.add(jb1); eastJpanel.add(jb2); eastJpanel.add(jb3); eastJpanel.add(jb4); eastJpanel.add(jb5); eastJpanel.add(jb6); // 给按钮添加监听器 //匿名内部类 jb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("开始")) { test.setB1("1"); System.out.println(" " + test.getB1()); } } }); jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("退出")) { int i = JOptionPane.showConfirmDialog(null, "请点击关闭按钮退出程序"); if (i == 0) { System.exit(0); } } } }); jb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("黑子先手")) { test.setB3("1"); } } }); jb4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("白子先手")) { test.setB3("-1"); } } }); jb5.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("保存")) ; try { // 调用写入方法 write(fileName); } catch (IOException e1) { e1.printStackTrace(); } } }); jb6.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("打开")) { try { // 调用读取文件的方法 open(fileName); } catch (IOException e1) { e1.printStackTrace(); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } } } }); // 设置棋盘的颜色 this.setBackground(Color.PINK); jf.add(this, BorderLayout.CENTER); jf.setVisible(true); g = jf.getGraphics(); // 获取绘画的图形 Graphics g = this.getGraphics(); // 实例化一个ChessLIstener类的监听对象 // ChessListener cl = new ChessListener(g,b1, b2,b3,b4); ButtonListener c2 = new ButtonListener(jb3, jb4); // 给事件源棋盘面板添加鼠标监听器方法,绑定事件处理类的对象 cl = new ChessListener(g, test, list); this.addMouseListener(cl); // 绘制棋盘 jf.setDefaultCloseOperation(3); } // 重绘操作,重写重绘方法 public void paint(Graphics g) { super.paint(g); drawChessTable(g); } // 绘制棋盘 private void drawChessTable(Graphics g) { for (int i = 0; i < Config.ROW; i++) { g.drawLine(i * Config.SIZE + Config.X, Config.Y, i * Config.SIZE + Config.X, Config.Y + (Config.COLUMN - 1) * Config.SIZE); } for (int i = 0; i < Config.COLUMN; i++) { g.drawLine(Config.X, i * Config.SIZE + Config.Y, Config.X + (Config.ROW - 1) * Config.SIZE, i * Config.SIZE + Config.Y); } } //写一个写入方法,将数据保存到文件里面 public boolean write(String fileName) throws IOException { this.list = cl.list; //写入对象 FileOutputStream fos = new FileOutputStream(fileName); ObjectOutputStream out = new ObjectOutputStream(fos); // 写入队列的长度 DataOutputStream dos = new DataOutputStream(fos); //writeInt方法,将棋子个数写入文件中 dos.writeInt(list.size()); for (int i = 0; i < list.size(); i++) { Chess chess = list.get(i); out.writeObject(chess); // System.out.println("aaaaaaaaaaa"); out.flush(); } //写完文件后关闭文件 dos.close(); out.close(); return true; } //定义一个打开文件的方法 public boolean open(String fileName) throws IOException,ClassNotFoundException { // for (int i = 0; i < list.size(); i++) { FileInputStream fis = new FileInputStream(fileName); ObjectInputStream input = new ObjectInputStream(fis); //首先读取原来队列的长度,即对象的个数 DataInputStream dis = new DataInputStream(fis); int listSize = dis.readInt(); for (int i = 0; i <listSize; i++) { //强制转型,读出对象 Chess chess = (Chess) input.readObject(); //判断并设置画布的颜色 if(chess.getColor()==1){ g.setColor(Color.black); }else{ g.setColor(Color.WHITE); } System.out.println(chess.getI()+"ppppppppppppppp"+ chess.getJ()); g.fillOval(chess.getI()+Config.CHESS_SIZE /4, chess.getJ()+Config.CHESS_SIZE , Config.SIZE, Config.SIZE); // chess = (Chess) input.readObject(); } //数据读取完毕,关闭文件 dis.close(); input.close(); return true; } }
?
?接下来是棋子监听器
import java.awt.Color; import java.awt.Graphics; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; import javax.swing.JButton; import javax.swing.JOptionPane; public class ChessListener extends MouseAdapter { private Graphics g; private int b3=0;// 判断黑白棋的依据 private Win win = new Win(); List<Chess> list; int longer = 0; int count = 0;// 保证黑白子交替出现 int flag = 0; Test test; public ChessListener(Graphics g, Test test, List<Chess> list) { // TODO Auto-generated constructor stub this.g = g; this.test = test; this.list = list; System.out.println(test.getB1() + "b2::::::::" + test.getB2()); } public void mouseReleased(MouseEvent e) { // System.out.println("222222222222 here b1 is: "+test.getB1()); if (test.getB1().equals("1")) { int x1 = e.getX();// 得到坐标 int y1 = e.getY(); // System.out.println(x1+" "+y1); for (int i = 0; i < Config.ROW; i++) { for (int j = 0; j < Config.COLUMN; j++) { // 判断此点是否已经被落子 if (Config.array[i][j] == 0) { // 得到当前的坐标 int x = Config.X + Config.CHESS_SIZE * i - Config.CHESS_SIZE / 2; int y = Config.Y + Config.CHESS_SIZE * j - Config.CHESS_SIZE / 2; if (x1 > (Config.X + Config.CHESS_SIZE * i - Config.CHESS_SIZE / 3) // 如果在三分之一范围内就落子 && x1 < (Config.X + Config.CHESS_SIZE * i + Config.CHESS_SIZE / 3) && y1 > (Config.Y + Config.CHESS_SIZE * j - Config.CHESS_SIZE / 3) && y1 < (Config.Y + Config.CHESS_SIZE * j + Config.CHESS_SIZE / 3)) { // 下黑子 if (count == 0) { g.setColor(Color.black); count++; b3 = 1; } else { // 下白子 g.setColor(Color.WHITE); count--; b3 = -1; } g.fillOval(x, y, Config.CHESS_SIZE, Config.CHESS_SIZE); Chess chess = new Chess(x, y, b3);// 实例化一个棋子对象,存储当前的坐标及颜色 System.out.println(x+"oooooo"+y); // 将该棋子对象存到队列里面去 list.add(chess); Config.array[i][j] = b3; if (win.validater(i, j)) { if (b3 == 1) { JOptionPane.showMessageDialog(null, "恭喜,黑棋胜利!"); test.setB1("0"); for (int i1 = 0; i1 < Config.ROW; i1++) { for (int j1 = 0; j1 < Config.COLUMN; j1++) { Config.array[i1][j1] = 0; } } } else { JOptionPane.showMessageDialog(null, "恭喜,白棋胜利!"); test.setB1("0"); for (int i1 = 0; i1 < Config.ROW; i1++) { for (int j1 = 0; j1 < Config.COLUMN; j1++) { // Config.array[i][j]=0; Config.array[i1][j1] = 0; } } } } } } } } } } }
?
按钮监听器
import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JButton; public class ButtonListener extends MouseAdapter{ private JButton jb3,jb4; private Component a; public ButtonListener(JButton jb3,JButton jb4){ this.jb3 = jb3; this.jb4 = jb4; } }
?
/** * 五子棋配置信息的接口 * */ public interface Config { int X = 20; int Y = 20; int ROW = 16; int COLUMN = 16; int SIZE = 30; int CHESS_SIZE = 30; int array[][] = new int[ROW][COLUMN]; }
?
反序列化棋子
//实例化一个棋子类可以用来反序列化棋子 import java.io.Serializable; public class Chess implements Serializable { private int i; private int j; private int Color; public Chess(int i ,int j,int Color){ this.i=i; this.j=j; this.Color=Color; } public int getI() { return i; } public void setI(int i) { this.i = i; } public int getJ() { return j; } public void setJ(int j) { this.j = j; } public int getColor() { return Color; } public void setColor(int color) { Color = color; } }
?
测试类
//用于测试按钮监听器是否奏效的测试类 public class Test { String b1="0", b2="0",b3="0",b4="0"; public String getB1() { return b1; } public String getB2() { return b2; } public String getB3() { return b3; } public void setB1(String b1) { this.b1 = b1; } public void setB2(String b2) { this.b2 = b2; } public void setB3(String b3) { this.b3 = b3; } }
?
备注:关于文件写入与输出的类
第一,ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。
第二,类 DataOutputStream
数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。
看一下效果图
?