Как уже было сказано, -cp предназначен только для указания jvm в командной строке, какой класс использовать для основного потока и где он может найти библиотеки (определить путь к классам). В -jar он ожидает, что путь к классу и основной класс будут определены в манифесте файла jar. Таким образом, другое предназначено для определения вещей в командной строке, в то время как другие находят их внутри манифеста jar. Нет разницы в производительности. Вы не можете использовать их одновременно, -jar переопределит -cp.
Хотя даже если вы используете -cp, он все равно проверит файл манифеста. Таким образом, вы можете определить некоторые пути к классам в манифесте, а некоторые - в командной строке. Это особенно полезно, когда у вас есть зависимость от стороннего jar-файла, который вы можете не предоставлять вместе со своей сборкой или не хотите предоставлять (например, ожидая, что он уже найден в системе, где он будет установлен). Таким образом, вы можете использовать его для создания внешних банок. Его местоположение может отличаться в зависимости от системы, или он может даже иметь другую версию в другой системе (но с одинаковыми интерфейсами). Таким образом, вы можете создать приложение с другой версией и добавить фактическую зависимость стороннего производителя к class-path в командной строке при его запуске в разных системах.