Ці можна ігнараваць выключэнне?

У Java, можна зрабіць метад, які мае кідае , які не правяраюцца.

Напрыклад:

public class TestClass {
    public static void throwAnException() throws Exception {
        throw new Exception();
    }
    public static void makeNullPointer() {
        Object o = null;
        o.equals(0);//NullPointerException
    }
    public static void exceptionTest() {
        makeNullPointer(); //The compiler allows me not to check this
        throwAnException(); //I'm forced to handle the exception, but I don't want to
    }
}
26

10 адказы

Вы можаце паспрабаваць і не рабіць нічога пра гэта:

public static void exceptionTest() {
    makeNullPointer(); //The compiler allows me not to check this
    try {
        throwAnException(); //I'm forced to handle the exception, but I don't want to
    } catch (Exception e) { /* do nothing */ }
}

Bear in mind, in real life this is extemely ill-advised. That can hide an error and keep you searching for dogs a whole week while the problem was really a cat(ch). (Come on, put at least a System.err.println() there - Logging is the best practice here, as suggested by @BaileyS.)

Unchecked exceptions in Java extend the RuntimeException class. Throwing them will not demand a catch from their clients:

// notice there's no "throws RuntimeException" at the signature of this method
public static void someMethodThatThrowsRuntimeException() /* no need for throws here */ {
    throw new RuntimeException();
}

Класы, якія пашыраюць RuntimeException не патрабуецца кідае дэкларацыі, а таксама.

І слова з Oracle аб гэтым:

<�Р> Вось у ніжняй радку асноўнага палажэнні: Калі кліент можна разумна чакаць, каб акрыяць ад выключэння, зрабіць яго правяраемым выключэнне. Калі кліент не можа нічога, каб акрыяць ад выключэння зрабіць, зрабіць гэта неправеранае выключэннем.
52
дададзена
Невялікае паляпшэнне было б толькі злавіць дакладны правяраеце выключэнне, што вы хочаце ігнараваць. Зусім няма неабходнасці глынаць <�я> усе </я> выключэння проста ігнараваць адзін адзін :)
дададзена аўтар Svish, крыніца
Слова ад Oracle супраць бягучай найлепшай практыкі для інтэрфейсу праграмавання і апрацоўкі/пераўтварэнні выключэнняў з аспектамі.
дададзена аўтар Danubian Sailor, крыніца
У сітуацыях, калі метад выклікае абанент ловіць і ігнаруе выключэнне моцна паказвае на дэфекты альбо які выклікае або выкліканага метаду. У некаторых выпадках дэфект можа быць звязана з тым, што DoSomething метад павінен, але не, забяспечвае TryDoSomething альтэрнатыўны. Калі клас або інтэрфейс з гэтым метадам добра усталяваны, глытанне, за выключэннем, хоць непрыгожа, можа быць адзіным практычным спосабам справіцца з сітуацыяй.
дададзена аўтар supercat, крыніца
Калі код выклікае метад, які абвешчаны як кідае правяраеце выключэнне, але чакаць, што канкрэтны выклік ня будзе на самой справе кінуць выключэнне, выключэнне павінна быць злоўлены і выкліканыя паўторна як не правяраецца тып выключэння (напрыклад, < код> RuntimeException ). Гэта не павінна быць проглочена. Адзіны раз, калі выключэнне варта праглынаць без прыняцця якіх-небудзь дзеянняў, калі метад з'яўляецца <�я> Вядома, што кінуць яго ў тых выпадках, прыкладанне не клапоціцца аб ; выключэння, якія, як чакаецца, ніколі не адбыцца не прыходзяць нават блізка да фітынг гэтым крытэры.
дададзена аўтар supercat, крыніца
Я заблакаваў задаваць пытанні, на жаль. Тым не менш, я выявіў, што ўсе выключэння робяць прыпынку патоку, нават калі вы іх злавіць. Але калі вы выкарыстоўваеце свой сцяг паток булева у цыкле у той час як замест таго, каб проста калі ўмова нітка выконваецца адзін раз - але цыкл, пакуль запускаюцца і працягвае ісці. Такім чынам, вы павінны перайсці ад выкарыстання, калі ўмовы ў той час.
дададзена аўтар Lealo, крыніца
Хто-небудзь здараецца ведаць кастрыраваны баран ніткі прымусова спыненыя некаторымі выключэннямі - нават калі вы ловіце гэтыя памылкі?
дададзена аўтар Lealo, крыніца
@ Jpmc26: Дзе-то ўздоўж лініі, не здабытае імя файла амаль напэўна адбываецца ад уваходу ў час выканання (файл канфігурацыі, ўводу дадзеных карыстальнікам, незалежна). Вось чаму гэта правяраецца; гэта памылка, якая можа адбыцца нават тады, калі сама праграма працуе правільна. Вядома, з пункту гледжання <�я> Функцыю , не так шмат можна зрабіць, калі файл не існуе ... але абанент (ці яго выклікае, ці .. .) мае большы выгляд прыкладання і яго намераў. Я мог бы разумна злавіць FileNotFoundException і (напрыклад) згадаць пытанне канфігурацыі, выкарыстоўвайце запасны варыянт, або прапануе карыстачу абраць існуючы файл.
дададзена аўтар cHao, крыніца
Я звычайна не маюць тыя варыянты з NullPointerException . Гэта выключэнне ніжняга ўзроўню; ён у асноўным кажа, што «падчас выканання не дазволіць нам зрабіць гэта», але не дае (спецыфічны) дастаткова інфармацыі, каб разумна аднавіць. Усё, што вы атрымаеце гэта трассирование, і гэта даволі бескарысна для карыстальніка.
дададзена аўтар cHao, крыніца
Уваход выключэння, але не ўвайсці двойчы. Я бачыў занадта шмат сістэм, дзе ж выключэнне было зарэгістравана некалькі разоў, таму што кожны выклік метаду ловіць, часопісы і rethrows іх. Звяртайцеся з імі на мяжы паміж модулямі, калі няма іншага месца, каб справіцца з імі.
дададзена аўтар Eric Jablow, крыніца
@Craig О, давай, каламбур прыносіць пост на зусім новы ўзровень: P
дададзена аўтар acdcjunior, крыніца
@ Jpmc26 У вас ёсць добры момант там. Не дзіўна, што назва гэтага артыкула ад Oracle з'яўляецца неправеранага Выключэнні - Супярэчнасці </а>. Я памятаю, як у C#, дзе першае, што яны зрабілі правяралася сістэма выключэння BASh ў Java ...
дададзена аўтар acdcjunior, крыніца
@Lealo Я не думаю, што яны ёсць, але гэта было некаторы час, так як я сапсаваў з імі. Я прапаную вам стварыць пытанне самастойна. Гэта вельмі актуальна.
дададзена аўтар acdcjunior, крыніца
Я хацеў downvote гэта для жудаснага каламбур, але я не мог узяць з сабой сябе, каб зрабіць гэта. +1 за добры адказ
дададзена аўтар Craig, крыніца
Вельмі добры пост. Іншая справа, што я хацеў бы прапанаваць, па меншай меры, запіс праігнараваны выключэнне ў рэгістратару.
дададзена аўтар Bailey S, крыніца
Я думаю, што, можа быць, гэтая лінія робіць лепш растлумачыць меркаванае выкарыстанне: «Выключэнне асяроддзя выканання ўяўляе праблемы, якія з'яўляюцца вынікам праблемы праграмавання, і, такім чынам, код кліента API не можа разумна чакаць, каб акрыяць ад іх або апрацоўваць іх у любым спосабам «. Іншымі словамі, RuntimeException s з'яўляюцца BONEHEAD выключэння, якія прыходзяць ад таго, калі праграміст забыўся растлумачыць нейкі выпадак ці запраграмаванага нешта няправільна, і выклікае абанент даў ваш код непрыдатным для выкарыстання дадзеных або аб'ектаў для працы з. Яны спосаб даць выклікаламу абаненту паведамленне пра памылку карыснай, каб даць ім няўцям, што яны зрабілі няправільна.
дададзена аўтар jpmc26, крыніца
Гэта прымушае задумацца, што яны маюць на ўвазе пад «разумна чакаць аднаўлення.» З пункту гледжання самой праграмы, не так шмат можна зрабіць, калі файл адсутнічае, але FileNotFoundException правяраецца. Лепшая праграма можа зрабіць, гэта паведаміць карыстальніка (пры ўмове, што ёсць спосаб, каб атрымаць выхад да карыстача, які не можа быць у выпадку планавага абслугоўвання ці што там у вас). Калі «паведамляе карыстальніка аб памылцы» лічыцца «разумным аднаўленне», то праграмы могуць «разумна чакаць, каб аднавіць» літаральна з якіх-небудзь выключэнняў, што робіць RuntimeException бескарысны.
дададзена аўтар jpmc26, крыніца

У Java ёсць два віды Выключэнні , правяраемых выключэнняў і неправераныя выключэнні.

  • Exception is a checked exception, must caught or thrown.
  • NullPointerException is a RuntimeException, (the compiler doesn’t forces them to be declared in the throws claus) you can ignore it, ,but it still may occur in the Runtime, and your application will crash.

З Exception дакументацыі:

<�Р> Клас Exception і любыя падкласы, якія не зьяўляюцца таксама падкласы   RuntimeException правяраюцца выключэнні. Правяраныя выключэння павінны быць   абвешчаны ў метадзе або канструктар кідкі пункт, калі яны могуць быць   кінутая выканання метаду або канструктара і размножваць   па-за метаду або канструктара мяжы.

З RuntimeException дакументацыі:

<�Р> RuntimeException суперкласса тых выключэнняў, якія могуць быць   выкінута падчас нармальнай працы віртуальнай машыны Java.      <�Р> RuntimeException і яго падкласы з'яўляюцца неправеранымі выключэннямі.   Unchecked выключэнне не павінна быць абвешчана ў метадзе або   канструктар кідкі пункт, калі яны могуць быць кінутыя на выкананне   метад або канструктар і распаўсюджваць за межамі метаду або   Канструктар мяжа.
3
дададзена
Вядома, калі вы ігнараваць NullPointerException (або любое выключэнне) (у адрозненне ад лавіць яго і выкінуць), ваша прыкладанне будзе ўрэзацца.
дададзена аўтар Michael Kjörling, крыніца

Ёсць 3 рэчы, якія вы можаце зрабіць:

  • Throw a RuntimeException (or something extending a RuntimeException, like NullPointerException, IllegalArgumentException,...), you don't have to catch these as they are unchecked exceptions.

  • Catch the exception and do nothing (not recommended) :

    public static void exceptionTest() {
        makeNullPointer(); //The compiler allows me not to check this
        try {
            throwAnException(); //I'm forced to handle the exception, but I don't want to
        } catch (Exception e) {
           //Do nothing
        }
    }
    
  • Change exceptionTest () declaration to say that it throws an Exception, and let the method calling it catch the Exception and do what is appropriate :

    public static void exceptionTest() throws Exception {
        makeNullPointer(); //The compiler allows me not to check this
        throwAnException(); //I'm no more forced to handle the exception
    }
    
3
дададзена
Я хацеў бы прапанаваць, што калі метад абвешчаны як кідаць правяраеце выключэнне, але канкрэтны выклік, як чакаецца, ніколі не кідаць, трэба злавіць правяраеце выключэнне і загарнуць яго ў чымсьці накшталт RuntimeException . На самай справе, я хацеў бы разгледзець такія паводзіны дарэчы, нават калі (магчыма, <�я> асабліва калі ) метад прыняцця выкліку, як чакаецца, кінуць гэта выключэнне ў нейкім іншым акалічнасці. Калі LoadDocument (радок файла) кідае FileNotFoundException , што варта паказаць, што імя_файла не знойдзены - не тое, што які-небудзь іншы неабходны файл як шаблон не было.
дададзена аўтар supercat, крыніца

Вы можаце выкарыстоўваць шчыліну ў Java Compiler. Дадайце наступны код:

public RuntimeException hideThrow(Throwable e) {
    if (e == null)
        throw new NullPointerException("e");
    this.hideThrow0(e);
    return null;
}

@SuppressWarnings("unchecked")
private  void hideThrow0(Throwable e) throws GenericThrowable {
    throw (GenericThrowable) e;
}

Вы можаце злавіць выключэнне, а затым выклікаць hideThrow за выключэннем кінуць яго без заўважаючы кампілятара. Гэта працуе з-за тыпу пры спробе ачысціць. Падчас кампіляцыі, GenericThrowable ўяўляе RuntimeException , таму што гэта тое, што мы праходзім. Падчас выканання GenericThrowable ўяўляе Throwable , таму што гэта асноўны тып у спецыфікацыі параметру тыпу.

3
дададзена

Не, гэта выклікае памылку кампілятара. Будучы правяраемым выключэнне, вы павінны альбо злавіць яго ці распаўсюджваць яго, абвясціўшы свой метад як патэнцыйна кідаць яго. Праверце гэта і гэта .

2
дададзена
Я не ўніз выбаршчыка, але ваш адказ крыху няпоўны, разгледзім @tarrsalah, вы можаце знайсці адказ
дададзена аўтар Grijesh Chauhan, крыніца
Адзначыў, хлопцы. Дзякуючы.
дададзена аўтар LexLythius, крыніца
Ня downvoter небудзь, але таксама рэкамендуецца падсумаваць важныя моманты, зробленыя ў любых спасылках, звязаных такім чынам, што адказ можа стаяць самастойна, нават калі звязаныя дакументы перамяшчаюцца або знікаюць.
дададзена аўтар Michael Kjörling, крыніца

Проста злавіць выключэнне і не робяць любую рэч з ім, пакінуць як ёсць і злавіць радавое выключэнне ў выпадку, калі вы не ведаеце канкрэтнага выключэння

try{
//Your logic goes here
}
catch(Exception e)//Exception is generic
{
//do nothing
}
1
дададзена

Іншыя адказы маюць рацыю, у тым, што яны правільна сказаць вам, што вы павінны зрабіць, але з'яўляецца на самой справе можна кінуць неабвешчаную правяраеце выключэнне. Ёсць некалькі спосабаў, як гэта можна зрабіць; самае простае:

public void methodThatSecretlyThrowsAnException() {
    Thread.currentThread().stop(new Exception());
}

або калі ваша мэта складаецца ў тым, каб абгарнуць існуючы метад, які робіць яго абвясціць выключэнне

public void methodThatSecretlyThrowsAnException() {
    try {
        methodThatAdmitsItThrowsAnException();
    } catch(final Exception e) {
        Thread.currentThread().stop(e);
    }
}

(Само сабой зразумела, вы ніколі не павінны рабіць гэта.)

1
дададзена

Я ведаю, што гэта немагчыма ў выпадку. Толькі бескантрольна выключэнне, кампілятар можа прапусціць праверыць. такія як RuntimeException.

1
дададзена
Я проста абнавіў свой адказ, гэта немагчыма ў выпадку (справа карыстальніка). А потым растлумачыць, калі карыстальнік сапраўды хоча кінуць выключэнне, якое не можа быць перахоплена, мы можам толькі выкарыстаць неправеранае выключэнне.
дададзена аўтар Stony, крыніца
Гэты адказ з'яўляецца ўнутрана супярэчлівым. Спачатку вы кажаце, што гэта немагчыма, то растлумачыць (вроде), як гэта магчыма. Што гэта будзе?
дададзена аўтар Michael Kjörling, крыніца

Не рэкамендуецца, каб пазбегнуць выключэння з пустым блокам злавіць, нават калі вы цалкам упэўненыя, што не будзе разбурацца пры любых абставінах. Часам мы не ведаем чалавечага фактару.

Калі вы ўпэўненыя, што выключэнне вельмі малаверагодна (калі не немагчыма), вы павінны стварыць свой уласны Exception і і загарнуць нечаканае выключэнне ў гэтым.

Напрыклад:

private class UnlikelyException extends RuntimeException {
    public UnlikelyException (Exception e){
        super (e);
    }
}

Затым абгарнуць ваш код з прымеркі злавіць блок і кідаць выключэнне, што вы не павінны злавіць

try {
   //Your code
} catch  (Exception e) {
    throw new UnlikelyException(e);
}
0
дададзена