П3. Обработка исключений
Важную роль играет обработка исключений (ошибок). Как правило, программные ошибки вызывают завершение приложение и выдачу диагностической информации. Во многих случаях при возникновении ошибок следует продолжить программу, предусмотрев выполнение определенных действий. Для обработки исключительных ситуаций используют конструкции типа try {…} catch(Exception e){…}. Написанный здесь образец является предельно общим. Поясним его следующим примером, где выполняется попытка деления на 0:
package zerodivision; import java.awt.*; import java.util.Scanner;
public class ZeroDivision {
public static void main(String[] args) {
System.out.println("Input first number"); Scanner input= new Scanner(System.in); int n1=input.nextInt(); System.out.println("Input second number"); int n2=input.nextInt();
try { double res=(double)(n1 / n2); System.out.printf("The division of %d by %d is %f",n1,n2,res); } catch(Exception ex) { System.out.println("Division by zero is forbidden!!! "+ex.getMessage()); } } } Если при вводе второго числа ввести 0, то возникнет исключение, которое будет перехвачено блоком catch, и на экране получим соответствующее сообщение run: Input first number 10 Input second number 0 Division by zero is forbidden!!! / by zero ПОСТРОЕНИЕ УСПЕШНО ЗАВЕРШЕНО (общее время: 6 секунд)
Программа при этом аварийно не завершается. Имеются разные классы исключений. Класс Exception – наиболее общий. В той же программе можно было использовать класс ArithmeticException:
catch(ArithmeticException ex) { System.out.println("Division by zero is forbidden!!! "+ ex.getMessage()); }
Наряду с try и catch используют также конструкцию finally, которая выполняется всегда, есть ошибка или нет. Пример
П4. Потоки
Поток – это ветвь основной программы, которая выполняется параллельно ей. Если нужно объявить, что класс использует поток, то в объявлении класса указываем интерфейс implements java.lang.Runnable. В данном интерфейсе объявлен метод run – основной метод потока. Когда поток стартует, то он начинает выполнять метод run. После завершения метода run поток автоматически уничтожается. Следующий фрагмент кода содержит пример метода run, который мы используем в учебном приложении
public void run() { while ( fThread != null){ try{ Thread.sleep (300); ++bellTolls;
javax.swing.ImageIcon img = new javax.swing.ImageIcon("E:\\work5\\Ex1bThread\\src\\Bella.gif"); aLabel.setIcon(img);
} catch (InterruptedException e) { } anOther(); if (this.isDone()) fThread = null; }
Здесь программное имя потокового объекта fThread. Происходит динамически повторяемое поочередное отображение двух картинок (icon) через паузу. Первая картинка создается в команде javax.swing.ImageIcon img = new javax.swing.ImageIcon("E:\\work5\\Ex1bThread\\src\\Bella.gif");
и отображается в поле label aLabel.setIcon(img);
Метод anOther() создает и отображает вторую картинку и имеет следующий вид
public void anOther(){ try{ Thread.sleep (300); javax.swing.ImageIcon img = new javax.swing.ImageIcon("E:\\work5\\Ex1bThread\\src\\Sun.gif"); aLabel.setIcon(img); } catch (InterruptedException e) { } }
Через паузу (Thread.sleep) в 300 милисекунд на ярлыке отображается другая картинка (Sun.gif).
Рисунок 141. Смена картинок в потоках
Приводим полный текст программы
package ex1bthread; import java.awt.*; import javax.swing.*;
public class Ex1bThread extends javax.swing.JFrame implements java.lang.Runnable{ public Ex1bThread() { aPanel = new javax.swing.JPanel(); aLabel = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setLocationRelativeTo(null); setPreferredSize(new java.awt.Dimension(50, 110)); setBackground(Color.PINK); add(aPanel); aPanel.add(aLabel); pack(); start(); }
public final void start() { if (fThread == null){ fThread = new java.lang.Thread (this); fThread.start(); } }
public void run() { while ( fThread != null){
try{ Thread.sleep (300); ++bellTolls;
javax.swing.ImageIcon img = new javax.swing.ImageIcon("E:\\work5\\Ex1bThread\\src\\Bellb.gif"); aLabel.setIcon(img); } catch (InterruptedException e) { } anOther(); if (this.isDone()) fThread = null; } }
public void anOther(){
try{ Thread.sleep (300); javax.swing.ImageIcon img =new javax.swing.ImageIcon("E:\\work5\\Ex1bThread\\src\\Sun.gif"); aLabel.setIcon(img);
} catch (InterruptedException e) { }
}
public boolean isDone() { boolean temp=false; if(bellTolls==COUNTS) { temp=true; bellTolls=0; } return temp; }
public static void main(String args[]) { Ex1bThread z= new Ex1bThread(); z.setVisible(true); z.setBackground(Color.PINK);
} private javax.swing.JLabel aLabel; private javax.swing.JPanel aPanel; Thread fThread; int bellTolls=0; final int COUNTS=50;
}
Конструктор основного класса Ex1bThread объявлен и реализован следующим образом
public Ex1bThread() { aPanel = new javax.swing.JPanel(); aLabel = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); setLocationRelativeTo(null);//размещает окно по центру //экрана setPreferredSize(new java.awt.Dimension(50, 110)); setBackground(Color.PINK); add(aPanel); aPanel.add(aLabel); pack(); start(); }
Создается панель (вид окна) aPanel = new javax.swing.JPanel(), на которую добавляем текстовый ярлык (Label) aPanel.add(aLabel).
Вызываем метод start для запуска потока
public final void start() { if (fThread == null){ fThread = new java.lang.Thread (this); fThread.start();//поток запускается командой start }
Смена картинок будет выполняться число раз, регулируемое переменной bellToll в методе isDone() (в приложении – 50 раз).
П5. Работа с файлами
Java предоставляет средства для низкоуровневого (на уровне байтов) доступа к файлам и средства высокоуровневого доступа при этом высокоуровневая объектная поточная переменная создается на основе низкоуровневой. Следующий фрагмент служит пояснением
FileOutputStream fout=new FileOutputStream("e:/my.txt"); DataOutputStream dout=new DataOutputStream(fout); dout.writeUTF("hello, File World! "); dout.close();
Переменная fout является низкоуровневой файловой поточной переменной. Она используется в конструкторе new DataOutputStream для создания высокоуровневой переменной dout,с помощью которой и осуществляется запись в файл e:/my.txt. Метод writeUTF выполняет запись текстовых данных информации в формате UNICODE. Чтобы прочитать записанные в файл текстовые данные, используем следующий код
FileInputStream finp=FileInputStream("e:/my.txt"); DataInputStream dinp=DataInputStream(finp); System.out.println(""+dinp.readUTF()); Dis.close(); Создадим оконное приложение для иллюстрации возможностей работы с файлами. package fileexample;
import java.awt.event.*; import java.io.*; import java.awt.*;
public class FileExample extends Frame implements ActionListener { Button bt=new Button("Выход"); Button bt1=new Button("Записать"); Button bt2=new Button("Прочитать"); TextField tf=new TextField();
public FileExample() { super("Work with Files"); setLayout(null); setBackground(new Color(250,200,120)); setSize(250,200); setVisible(true); add(bt); add(bt1); add(bt2); add(tf); bt.addActionListener(this); bt1.addActionListener(this); bt2.addActionListener(this); bt.setBounds(20,40,100,20); bt1.setBounds(20,65,100,20); bt2.setBounds(20,90,100,20); tf.setBounds(20,115,150,20);
} public void actionPerformed(ActionEvent ae) {
if(ae.getSource()==bt1) { try{ FileOutputStream fout=new FileOutputStream("e:/work/my.txt"); DataOutputStream dout=new DataOutputStream(fout); dout.writeUTF("Hello, File World!"); dout.close(); } catch(Exception ex){} } else if(ae.getSource()==bt) System.exit(0);
else if(ae.getSource()==bt2) { try{ FileInputStream finp= new FileInputStream("e:/work/my.txt"); DataInputStream dinp=new DataInputStream(finp); String s=dinp.readUTF(); dinp.close(); tf.setText(s); } catch(Exception ex) {} }
}
public static void main(String[] args) { new FileExample();
} }
Результат работы приложения показан на рисунке 142
Рисунок 142. Чтение и запись в файлы
Для записи строк в формате ASCII используется поточный класс PrintStream, как показано ниже
try{ FileOutputStream fout=new FileOutputStream("e:/work/my.txt"); PrintStream pstr=new PrintStream(fout); pstr.println("Hello, File World"); pstr.close(); } catch(Exception ex){} } else if(ae.getSource()==bt2) { try{ FileInputStream finp= new FileInputStream("e:/work/my.txt"); DataInputStream dinp=new DataInputStream(finp); String s=dinp.readLine(); dinp.close(); tf.setText(s); } catch(Exception ex) {} }
Изменим несколько наше приложение с тем, чтобы выбирать файл из окна файлового диалога. Окно файлового диалога создается и отображается следующим образом
FileDialog fd=new FileDialog(this, "FileOpening"); fd.show();
В конструкторе FileDialog указывается режим открытия файла ("FileOpening"). Имя выбранного файла получаем с помощью команды
String s=fd.getFile();
С учетом сказанного приложение можно переписать следующим образом.
package fileexample;
import java.awt.event.*; import java.io.*; import java.awt.*; public class FileExample extends Frame implements ActionListener { Button bt=new Button("Выход"); Button bt1=new Button("Записать"); Button bt2=new Button("Прочитать"); TextField tf=new TextField();
public FileExample() { super("Work with Files"); setLayout(null); setBackground(new Color(250,200,120)); setSize(250,200); setVisible(true); add(bt); add(bt1); add(bt2); add(tf); bt.addActionListener(this); bt1.addActionListener(this); bt2.addActionListener(this); bt.setBounds(20,40,100,20); bt1.setBounds(20,65,100,20); bt2.setBounds(20,90,100,20); tf.setBounds(20,115,150,20);
} public void actionPerformed(ActionEvent ae) { if(ae.getSource()==bt1) { try{ FileOutputStream fout=new FileOutputStream("e:/work/my.txt"); DataOutputStream dout=new DataOutputStream(fout); dout.writeUTF("Hello, File World!"); dout.close(); } catch(Exception ex){} } else if(ae.getSource()==bt) System.exit(0);
else if(ae.getSource()==bt2) { try{ FileDialog fd=new FileDialog(this,"FileOpening"); fd.show(); String s1=fd.getFile(); FileInputStream finp= new FileInputStream("e:/work/my.txt"); DataInputStream dinp=new DataInputStream(finp); String s=dinp.readUTF(); dinp.close();
tf.setText(s); }
catch(Exception ex) {} } }
public static void main(String[] args) { new FileExample();
}}
Окно приложения показано на рисунке 143.
Рисунок 143. Окно приложения с файловым диалогом
Для произвольного доступа используется класс RandomAccessFile. Для доступа к данным используем метод seek(long position). Положение указателя возвращает метод long getFilePointer(). Пример записи в файл целых чисел командой writeInt дает следующий код
package mylabs; import java.awt.*; import java.awt.event.*; import java.io.*;
class lab1_10 extends Frame implements ActionListener { Button b=new Button("Exit"); Button b1=new Button("Write to File"); Button b2=new Button(" Read from File");
public lab1_10() { setLayout(null); setBackground(new Color(240,230,100)); setSize(300,300); setVisible(true); add(b); add(b1); add(b2); b.addActionListener(this); b1.addActionListener(this); b2.addActionListener(this); b.setBounds(20,30,100,20); b1.setBounds(20,60,100,20); b2.setBounds(20,90,100,20); } public void actionPerformed(ActionEvent ae) { if(ae.getSource()==b) System.exit(0); else if(ae.getSource()==b1) { try{
RandomAccessFile raf= new RandomAccessFile("temp.dat","rw"); for (int i=0;i<10;i++) raf.writeInt(i); raf.close(); } catch(Exception ex){} } else if(ae.getSource()==b2) { try{
RandomAccessFile raf= new RandomAccessFile("temp.dat","rw"); Graphics g=getGraphics();
for (int i=0;i<10;i++) { raf.seek(i*4); int z=raf.readInt(); g.drawString(""+z,130,50+20*i); }
raf.close(); } catch(Exception ex) {} } } } public class lab1_11{ public static void main(String[] args) { lab1_10 app=new lab1_10(); } }
Для записи в файл используем фрагмент
try{
RandomAccessFile raf= new RandomAccessFile("temp.dat","rw"); for (int i=0;i<10;i++) raf.writeInt(i); raf.close(); } catch(Exception ex){} }
Запись целых чисел выполняет метод writeInt.
Для записи чисел в формате с плавающей точкой используют метод writeFloat. Для записи чисел с фиксированной точкой используют метод writeDouble. Для записи строки в формате Unicode – метод writeUTF. Чтение осуществляется соответственно методами readInt, readFloat, readDouble, readUTF. Однако чтение нужно выполнять с позиционированием головки чтения/записи. В нашем примере позиционирование реализовано в фрагменте:
for (int i=0;i<10;i++) { raf.seek(i*4); int z=raf.readInt(); ……
Метод seek устанавливает указатель на указанное смещение в байтах относительно начала. Целое число занимает 4 байта. Поэтому выполняем умножение i*4. Вещественные числа занимают 8 байтов. Следующий фрагмент дает иллюстрацию
try{
RandomAccessFile raf= new RandomAccessFile("temp.dat","rw"); Graphics g=getGraphics();
for (int i=0;i<10;i++) { raf.seek(i*8); double z=raf.readDouble(); g.drawString(""+z,130,50+20*i); }
raf.close();
}
Популярное: Генезис конфликтологии как науки в древней Греции: Для уяснения предыстории конфликтологии существенное значение имеет обращение к античной... Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас... Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (211)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |