Чому при виклику функції необхідне “throws Exception”?


97
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

Чому компілятор повідомляє , що методи show2(), show3()і main()є

незареєстрований виняток Виняток, який потрібно зловити або оголосити кинутим

коли я видаляю throws Exceptionз цих методів?


2
@PaulTomblin main, безумовно, можна оголосити, що кидає виняток. Якщо це станеться, JVM вимкнеться. Це настільки близько до ігнорування, наскільки це дозволить компілятор.
Таймон,

Коли викликаний метод ( Methdod1 ) кидає Exception, ми повинні визначити метод виклику ( Method2 ) за допомогою throws Exception; якщо ми не передаємо цей виняток методу виклику. Метою цього є надання інформації про виклик методу (Метод 3 ) Методу 2 про те, що Метод2 може викликати виняток, і Ви повинні обробляти його тут, інакше це може перервати вашу програму.
Rito

Подібним чином, якщо Method3 не обробляє виняток у своєму тілі, йому довелося визначити throws Exceptionу своєму визначенні методу, щоб дати голову методу виклику. продовження попереднього коментаря
Rito

Відповіді:


144

Як ви вже знаєте, у Java, винятки можна розділити на два: той, якому потрібне throwsречення, або який повинен бути оброблений, якщо ви не вказали той, а інший - ні. Тепер подивіться наступний малюнок:

введіть тут опис зображення

У Java ви можете кинути все, що розширює Throwableклас. Однак вам не потрібно вказувати throwsречення для всіх класів. Зокрема, класи, які є Errorабо RuntimeExceptionабо будь-яким із підкласів цих двох. У вашому випадку Exceptionце не підклас Errorабо RuntimeException. Отже, це перевірений виняток і повинен бути вказаний у throwsпункті, якщо ви не обробляєте цей виняток. Ось чому вам потрібно було throwsпункт.


З підручника Java :

Виняток - подія, яка відбувається під час виконання програми, що порушує нормальний потік інструкцій програми.

Тепер, як ви знаєте, винятки класифікуються на дві: перевірені та не позначені. Чому саме ця класифікація?

Перевірений виняток: Вони використовуються для представлення проблем, які можна відновити під час виконання програми. Зазвичай вони не винні в програмісті. Наприклад, файл, зазначений користувачем, неможливо прочитати, або немає доступного мережевого підключення тощо. У всіх цих випадках нашій програмі не потрібно виходити, натомість вона може виконувати дії, такі як попередження користувача, або переходити до резервної копії механізм (наприклад, робота в режимі офлайн, коли мережа недоступна) тощо.

Невизначені винятки: їх знову можна розділити на два: Помилки та Виконання RuntimeExceptions. Однією з причин, за якою їх не можна перевіряти, є те, що їх кількість численні, і необхідність обробляти всі з них буде захаращувати нашу програму та зменшувати її чіткість. Інша причина:

  • Винятки під час виконання: Зазвичай вони трапляються через несправність програміста. Наприклад, якщо ArithmeticExceptionподіл на нуль відбувається або ArrayIndexOutOfBoundsExceptionвідбувається, це відбувається тому, що ми недостатньо обережні в кодуванні. Зазвичай вони трапляються через деякі помилки в нашій логіці програми. Отже, їх потрібно очистити, перш ніж наша програма перейде в режим виробництва. Вони не перевіряються в тому сенсі, що наша програма повинна вийти з ладу, коли вона трапиться, щоб ми, програмісти, могли її вирішити під час розробки та тестування.

  • Помилки: Помилки - це ситуації, з яких програма зазвичай не може відновитись. Наприклад, якщо StackOverflowErrorвиникає a , наша програма не може зробити багато, наприклад, збільшити розмір стека викликів функцій програми. Або якщо таке OutOfMemoryErrorтрапляється, ми не можемо багато зробити для збільшення обсягу оперативної пам'яті, доступної для нашої програми. У таких випадках краще вийти з програми. Ось чому вони зроблені неперевіреними.

Для отримання детальної інформації див .:


що я отримав від вашої відповіді, так це те, що клас Error та його підкласи та клас RuntimeException та його підкласи потрапляють під неперевірений виняток (наприклад, System.out.println (5/0); кидати не потрібно, оскільки це є виняток виконання, але все-таки ми можемо застосувати try catch) і клас Exception перевірений, тому нам потрібно оголосити речення throws у цьому методі та кожному методі, який його викликає
nr5

Ще одне запитання: якщо винятки класифікуються як неперевірені та перевірені, особливо непровірені (помилки виконання), щоб уникнути більшої кількості помилок під час компіляції?
nr5

@Jomoos - скажімо, що код всередині методу кидає IOException. Тоді, чи нормально в декларації методу вводити "throws Exception"?
MasterJoe

ой Я зрозумів це зараз. є виняток із правил ієрархії винятків. Робить. Ідеально. Почуття. Дякую Java.
JJS

25

Java вимагає обробки або декларування всіх винятків. Якщо ви не обробляєте виняток, використовуючи блок try / catch, тоді він повинен бути оголошений у підписі методу.

Наприклад:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

Має бути записано як:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

Таким чином ви можете позбутися декларації "throws Exception" у декларації методу.


7
Усі винятки, які не є підкласами RuntimeException, тобто.
yshavit

якщо є якийсь інший клас, такий як Exception, який перевіряється?
nr5

1
Що ви маєте на увазі? Оскільки для всіх об'єктів винятків базовим класом є "Виняток", якщо ви впіймаєте об'єкт "Виняток" (як у моєму прикладі), він захопить будь-яке виключення, яке буде видане. Щоб бути більш конкретним (оскільки різні винятки, ймовірно, вимагають різних способів поводження з речами), ви повинні мати кілька блоків catch.
jebar8,

якби я сказав, що перевірені винятки потрібно обробляти @ час компіляції і ловити під час виконання. Маю рацію ? якщо так, то формулювання того самого речення для Неперевіреного винятку буде?
nr5

@ jebar8 - ви плутаєте Java з .NET - у Java, що передаються, має успадковуватись Throwable(успадкування Exceptionтакож працює, оскільки воно розширюється Throwable, але це не потрібно).
BrainSlugs83,

4

Exceptionє перевіреним класом винятків. Отже, будь-який код, який викликає метод, який оголошує, що він throws Exceptionповинен його обробляти або оголошувати.


Будь-який метод у ланцюжку оголошується для викиду Exception, включаючи main. То де проблема?
Пол Томблін,

@PaulTomblin я запитував, що чому потрібно писати, викидає виняток у виклику функцій, викликаючи функцію, яка видає виняток
nr5

Добре, я не зрозумів, чому ви запитуєте про помилку компілятора, яку ви насправді не отримували з коду, який ви опублікували. Це дивний спосіб запитати.
Пол Томблін,

4

throws ExceptionДекларація являє собою автоматизований спосіб відстеження методів , які могли б кинути виняток для очікуваних , але неминучих причин. Декларація, як правило, конкретно стосується типу або типів винятків, які можуть бути створені, таких як throws IOExceptionабо throws IOException, MyException.

Ми всі маємо або в кінцевому підсумку напишемо код, який несподівано зупиняється і повідомляє про виняток через те, чого ми не передбачали до запуску програми, наприклад, поділ на нуль або індекс поза межами. Оскільки метод не очікував помилок, їх не вдалося "зловити" та обробити за допомогою пропозиції try catch. Будь-які підозрілі користувачі методу також не знали б про цю можливість, і їх програми також зупинялися б.

Коли програміст знає, що можуть виникати певні типи помилок, але він хотів би обробляти ці винятки поза методом, метод може "кидати" один або кілька типів винятків до виклику методу замість того, щоб обробляти їх. Якщо програміст не оголосив, що метод (може) створити виняток (або якщо Java не мала можливості оголосити його), компілятор не міг би знати, і про це мав би знати майбутній користувач методу, ловити та обробляти будь-які винятки, які може викликати метод. Оскільки програми можуть мати багато рівнів методів, написаних багатьма різними програмами, стає важко (неможливо) відстежувати, які методи можуть створювати винятки.

Незважаючи на те, що Java має можливість оголосити винятки, ви все одно можете написати новий метод з необробленими та незадекларованими винятками, і Java скомпілює його, і ви зможете запустити його і сподіватися на краще. Що Java не дозволить вам зробити, це скомпілювати ваш новий метод, якщо він використовує метод, який був оголошений як викид (и), за винятком випадків, коли ви або обробляєте заявлені винятки у своєму методі, або оголошуєте свій метод як викидання того самого виняток (и) або якщо є кілька винятків, ви можете впоратися з деякими, а решту кинути.

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

Приємна річ у цьому типі рішення полягає в тому, що, коли компілятор повідомляє, Error: Unhandled exception type java.io.IOExceptionвін надає номер файлу та рядок методу, який було оголошено для видалення виключення. Потім ви можете просто передати гроші і оголосити, що ваш метод також "кидає IOException". Це можна зробити аж до основного методу, де це призведе до того, що програма зупиниться і повідомить користувача про виняток. Однак краще вловити виняток і впоратися з ним приємно, наприклад, пояснивши користувачеві, що сталося, і як це виправити. Коли метод захоплює та обробляє виняток, він більше не повинен оголошувати виняток. Бакс там зупиняється, так би мовити.


0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

Лише незначні зміни у вашій програмі. Що, здається, багато хто не розуміє щодо головної проблеми, - це коли ви видаляєте виняток, вам потрібно його обробляти, не потрібно там же (наприклад, метод show1,2,3 у вашій програмі), але спочатку ви повинні викликати метод абонента всередині "головного". одним словом, є "кинути", має бути "зловити / спробувати", навіть якщо це не той самий метод, де трапляється виняток.


0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Оскільки в методі show () є перевірений виняток, який не обробляється цим методом, ми використовуємо ключове слово throws для розповсюдження винятку.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Оскільки ви використовуєте метод show () у методі show2 (), і ви поширили виняток принаймні, вам слід обробляти тут. Якщо ви не обробляєте виняток тут, тоді ви використовуєте ключове слово throws. Отже, це причина використання ключового слова throws у підписі методу.


0

Якщо ви поширюєте виняток, оголошуючи директиву throws у підписі поточного методу, тоді десь вгору по рядку або стеку викликів для обробки винятків повинна використовуватися конструкція try / catch.


Цей коментар слід додати до розділу коментарів, оскільки він не надає підтверджуваної відповіді або прикладу такого. - stackoverflow.com/help/how-to-answer
Пол Доусон,

-1

В основному, якщо ви не обробляєте виняток у тому самому місці, що і його кидаєте, тоді ви можете використовувати "викид винятку" у визначенні функції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.