Più o meno anche in C++. La differenza è che usando i template non leghi il codice a uno specifico tipo di dato, ma a uno generico che verrà esplicitato in seguito.
Prendi la classica funzione max
codice:
template <typename Tx>
const Tx& max(const Tx& a, const Tx&b) {
    return ( a < b ) ? b : a; 
}
Quante volte dovresti riscrivere quel codice per adattarlo, ad esempio ai tipi base? E per una classe?
Con un template lo scrivi una volta. Sarà il compilatore a scrivere il resto per te.
Altro esempio (molto semplificato preso dallo standard):
codice:
template <typename Tx, std::size_t N>
class array {
    Tx data[N];
    public:
        Tx& operator[](std::size_t n) {
            return data[N];
        }
};
Quante volte dovresti riscrivere in Java quel codice per adattarlo, ad esempio ai tipi base? E per una classe?
Del resto non credo sia un caso se in Java siano stati introdotti i generics.