Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторна робота №4.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
119.81 Кб
Скачать

Створення користувальницьких класів виключень

Як ми вже відзначали, допускається створення власних класів виключень. Для цього досить створити свій клас, успадкувавши його від будь-якого спадкоємця java.lang.Throwable (або від самого Throwable).

Приклад:

public class UserException extends Exception {

public UserException() {

super();

}

public UserException(String descry) {

super(descry);

}

}

Відповідно, дане виключення буде створюватися в такий спосіб:

throw new UserException(

"Додатковий опис");

Перевизначення методів і виключення

При перевизначенні методів варто пам'ятати, що якщо перевизначений метод повідомляє список можливих виключень, то він не може розширювати цей список, але може його звужувати. Розглянемо приклад:

public class BaseClass{

public void method () throws IOException {

...

}

}

public class LegalOne extends BaseClass {

public void method () throws IOException {

...

}

}

public class LegalTwo extends BaseClass {

public void method () {

...

}

}

public class LegalTree extends BaseClass {

public void method ()

throws

EOFException,MalformedURLException {

...

}

}

public class IllegalOne extends BaseClass {

public void method ()

throws

IOException,IllegalAccessException {

...

}

}

public class IllegalTwo extends BaseClass {

public void method () {

...

throw new Exception();

}

}

У цьому випадку:

  • визначення класу LegalOne буде коректним, тому що перевизначення методу method() вірне (список помилок не змінився);

  • визначення класу LegalTwo буде коректним, тому що перевизначення методу method() вірне (новий метод не може викидати помилок, а виходить, не розширює список можливих помилок старого методу);

  • визначення класу LegalTree буде коректним, тому що перевизначення методу method() буде вірним (новий метод може створювати виключення, які є підкласами виключення, порушуваного в старому методі, тобто список звузився);

  • пропрерозподіл класу IlegalOne буде некоректним, тому що перевизначення методу method() невірно (IllegalAccessException не є підкласом IOException, список розширився);

  • визначення класу IlegalTwo буде некоректним: хоча заголовок method() оголошений вірно (список не розширився), у тілі методу кидається виключення, не зазначене в throws.

Особливі випадки

Під час виконання коду можуть виникати ситуації, які майже не описані в літературі.

Розглянемо таку ситуацію:

import java.io.*;

public class Test {

public Test() {

}

public static void main(String[] args) {

Test test = new Test();

try {

test.doFileInput("bogus.file");

}

catch (IOException ex) {

System.out.println("Second exception handle stack trace");

ex.printStackTrace();

}

}

private String doFileInput(String fileName)

throws FileNotFoundException,IOException {

String retStr = "";

java.io.FileInputStream fis = null;

try {

fis = new java.io.FileInputStream(fileName);

}

catch (FileNotFoundException ex) {

System.out.println("First exception handle stack trace");

ex.printStackTrace();

throw ex;

}

return retStr;

}

}

Результат роботи буде виглядати в такий спосіб:

java.io.FileNotFoundException: bogus.file (The system cannot find

the file specified)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.<init>(FileInputStream.java:64)

at experiment.Test.doFileInput(Test.java:33)

at experiment.Test.main(Test.java:21)

First exception handle stack trace

java.io.FileNotFoundException: bogus.file (The system cannot find

the file specified)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.<init>(FileInputStream.java:64)

at experiment.Test.doFileInput(Test.java:33)

at experiment.Test.main(Test.java:21)

Second exception handle stack trace

Тому що при вторинному порушенні використається той самий об'єкт Exception, стік в обох випадках буде містити ту саму послідовність викликів. Тобто при повторному порушенні виключення, якщо ми використаємо той же об'єкт, зміни його параметрів не відбувається.

Рассмотрим інший приклад:

import java.io.*;

public class Test {

public Test() {

}

public static void main(String[] args) {

Test test = new Test();

try {

test.doFileInput();

}

catch (IOException ex) {

System.out.println("Exception hash code " + ex.hashCode());

ex.printStackTrace();

}

}

private String doFileInput()

throws FileNotFoundException,IOException{

String retStr = "";

java.io.FileInputStream fis = null;

try {

fis = new java.io.FileInputStream("bogus.file");

}

catch (FileNotFoundException ex) {

System.out.println("Exception hash code " + ex.hashCode());

ex.printStackTrace();

fis = new java.io.FileInputStream("anotherBogus.file");

throw ex;

}

return retStr;

}

}

java.io.FileNotFoundException: bogus.file (The system cannot find

the file specified)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.<init>(FileInputStream.java:64)

at experiment.Test.doFileInput(Test.java:33)

at experiment.Test.main(Test.java:21)

Exception hash code 3214658

java.io.FileNotFoundException: (The system cannot find the path

specified)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.<init>(FileInputStream.java:64)

at experiment.Test.doFileInput(Test.java:38)

at experiment.Test.main(Test.java:21)

Exception hash code 6129586

Нескладно помітити, що, хоча послідовність викликів та сама, у викликуваному й зухвалому методах обробляються різні об'єкти виключень.