Comme déjà dit, le -cp est juste pour dire au jvm dans la ligne de commande quelle classe utiliser pour le thread principal et où il peut trouver les bibliothèques (définir classpath). En -jar, il s'attend à ce que le class-path et la classe principale soient définis dans le manifeste du fichier jar. Ainsi, l'un sert à définir les choses en ligne de commande et l'autre à les trouver dans le manifeste du fichier jar. Il n'y a pas de différence de performance. Vous ne pouvez pas les utiliser en même temps, -jar remplacera le -cp.
Même si vous utilisez -cp, il vérifiera toujours le fichier manifeste. Vous pouvez donc définir certains des chemins de classe dans le manifeste et d'autres dans la ligne de commande. Ceci est particulièrement utile lorsque vous avez une dépendance sur un jar tiers, que vous ne fournissez pas avec votre compilation ou que vous ne voulez pas fournir (en espérant qu'il soit déjà trouvé sur le système où il doit être installé par exemple). Vous pouvez donc l'utiliser pour fournir des jars externes. Son emplacement peut varier d'un système à l'autre ou il peut même avoir une version différente sur différents systèmes (mais avec les mêmes interfaces). De cette façon, vous pouvez construire l'application avec une autre version et ajouter la dépendance réelle de la tierce partie à class-path sur la ligne de commande lors de l'exécution sur différents systèmes.