Всё просто: o instanceof Integer просто проверяет, является ли реальный тип объекта o типом Integer.
Вы и правда можете создать несколько методов для вашей логики, один для Integer, другой для String. Но если к вам приходит Object, вы не сможете вызвать нужный метод, потому что не знаете, какого реально типа ваш объект. Вот для того, чтобы это выяснить, и нужен instanceof.
Кстати, использовать конструкцию switch с instanceof не выйдет, switch требует примитивные типы или String*. Но вы можете написать цепочку if'ов:
if (x instanceof Integer) {
// что-то сделать с (Integer)x
} else if (x instanceof String) {
// что-то сделать с (String)x
} else {
// ну не шмагла я определить тип
}
В правильной, хорошо написанной программе, количество instanceof и подобых конструкций обычно невелико: имеет смысл избегать передачи нетипизированных объектов (например, параметров типа Object), а там, где код должен работать с параметрами различного типа, использовать дженерики. Однако иногда приходится пользоваться подходом с instanceof, например, при взаимодействии с API, которое было написано ещё до прихода дженериков.
Ещё по теме:
*Или enum, или врапперы на примитивные типы наподобие Character.
switch требует примитивные типы– а как жеString? – post_zeew Jan 26 '17 at 16:43switchпроисходит их автораспаковка, поэтому Ваше выражение для них справедливо :) – post_zeew Jan 26 '17 at 16:52