Mazinger
Mazinger

Reputation: 653

Catching array exception

Hello everybody and thanks in advance.

I get an error in an array line of code. I have read all threads about this and still can't handle the exception properly, causing my app force closing.

Here is my code...

    public boolean HoraErronea(String HoraAValidar) throws IndexOutOfBoundsException
{
    String HoraIntroducida = HoraAValidar;
    boolean HoraErronea = false;

    if(HoraIntroducida.length() < 3 || HoraIntroducida.length() > 5)
    {
        HoraErronea = true;
    }
    else
    {
        try
        {
            HoraIntroducida = HoraIntroducida.replace("-", ":");
            String[] HoraTroceada = HoraIntroducida.split(":");

            int hora = HoraTroceada[0].equals("")?-1:Integer.parseInt(HoraTroceada[0]);
            int minuto = HoraTroceada[1].equals("")?-1:Integer.parseInt(HoraTroceada[1]);

            if(!((hora >= 0 && hora <= 24) && (minuto >= 0 && minuto <= 59)))
            {
                HoraErronea = true;
            }
        }
        catch (IndexOutOfBoundsException e)
        {
            e.printStackTrace();
        }
    }

    return HoraErronea;
}

Ok, the thing is when "HoraIntroducida" has no ":", then "HoraTroceada[1]" doesn't exists, so my code broke throwing this message...

E/MessageQueue-JNI: java.lang.ArrayIndexOutOfBoundsException: length=1; index=1 at com.essimple.essley.FuncionesActivity.HoraErronea(FuncionesActivity.java:366) at com.essimple.essley.CalendarioActivity.ValidaDatos(CalendarioActivity.java:483) at com.essimple.essley.CalendarioActivity.onBackPressed(CalendarioActivity.java:523) at android.app.Activity.onKeyUp(Activity.java:2725) at android.view.KeyEvent.dispatch(KeyEvent.java:2699) at android.app.Activity.dispatchKeyEvent(Activity.java:3026) at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:547) at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:57) at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:315) at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:317) at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4327) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4298) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3849) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3902) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3868) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3995) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3876) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4052) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3849) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3902) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3868) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3876) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3849) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3902) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3868) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4028) at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4189) at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2365) at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:1961) at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:1952) at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2342) at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:323) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:6077) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

I know I could check HoraTroceada's length and prevent the exception, but I'd like to do it in a better coding behaviour, catching the exception.

So please, can somebody tell me what is wrong about this?. Thank you everybody for your time and attention.

Upvotes: 0

Views: 650

Answers (5)

Stan Ivanov
Stan Ivanov

Reputation: 329

As the other answers have suggested you are improperly using the array indices. You should always test to see if the returned object is what you expected. In your case you are expecting an array of size 2. Then make this check explicit and handle the error situation correctly.

Generally speaking you should always be checking the outputs of the methods you call. You should handle the inconsistencies appropriately like throwing an exception or displaying an error message. Check that the returned object is:

  • not NULL
  • not in the specific range you are looking for
  • not empty
  • is of the right type

If inconsistency is detected, then throw an exception and quit early from your method. Otherwise you are risking passing invalid data to deeper parts of your code which can lead to data corruption and undefined behaviour.

You can find more tips at handling exceptions in my article: Exceptions Guidelines

Upvotes: 0

Steven Bond
Steven Bond

Reputation: 21

To verify null reference it is necessary to use if statement:

Object ref = null;

if(ref != null) {

System.out.println(ref.toString());

}

instead of using catch statement

Upvotes: 2

Kona Suresh
Kona Suresh

Reputation: 1854

Based on your Exception:

java.lang.ArrayIndexOutOfBoundsException: length=1; index=1

HoraTroceada contains only one value. so that length is 1.

so we can't access "HoraTroceada[1]" this value.

So before going to do first check this character "-" is available or not like this

if(HoraIntroducida.contains("-"){
 HoraIntroducida = HoraIntroducida.replace("-", ":");
String[] HoraTroceada = HoraIntroducida.split(":");
}

It should be help full.

Upvotes: 1

Tahir Hussain Mir
Tahir Hussain Mir

Reputation: 2626

Your code lacks "runtime exception handling".
See How:

 String HoraIntroducida = HoraAValidar;

Let us suppose, HoraValidar is just "1". Hence HoraIntroducida just holds "1".
Length is 1

String[] HoraTroceada = HoraIntroducida.split(":");

Since in above case, there will be just one element in HoraTroceada.

int minuto = HoraTroceada[1].equals("")?-1:Integer.parseInt(HoraTroceada[1]);

Here You are accessing element number 2 when You have just one element in your array. So expect the runtime error there.

So, solution would be

if(HoraTroceada.length == 1)
    int hora = HoraTroceada[0].equals("")?-1:Integer.parseInt(HoraTroceada[0]);
if(HoraTroceada.length == 2)
    int minuto = HoraTroceada[1].equals("")?-1:Integer.parseInt(HoraTroceada[1]);

Upvotes: 1

Hobbit
Hobbit

Reputation: 611

Before accessing the index , check the length of the array if it's greater than 0 then access the index

if(HoraTroceada.length > 0){
    int hora = HoraTroceada[0].equals("")?-1:Integer.parseInt(HoraTroceada[0]);
        int minuto = HoraTroceada[1].equals("")?-1:Integer.parseInt(HoraTroceada[1]);
}

Upvotes: 0

Related Questions