Хотел сначала написать это как комментарий к предыдущему ответу, но решил, что этот ответ все-таки не до конца верен. Тут человек спрашивает скорее "зачем нужны типы byte и short, если есть int", а не "когда нужно оптимизировать". На вопрос "когда нужно оптимизировать" ответ, безусловно, правильный.
Типы с разрядностью, меньшей чем у int, нужно использовать только с точки зрения экономии памяти, например, в больших массивах или классах с большим количеством полей. Использовать их в качестве локальных переменных не имеет смысла, т.к. процессор в любом случае оперирует типами размером с машинное слово (а Java на 16-битных машинах не работает, так ведь?). Т.е. об оптимизации вообще речи не идет, разницы нет, и в качестве локальных переменных типы byte и short, в принципе, появляться не должны. А вот если у тебя массив из over9000 элементов, в качестве элементов которого пойдет и short, то int использовать не стоит.