Building a sentence out of values with + works, but it gets hard to read as soon as there are more than two pieces. String.format() lets you write the sentence once and drop the values into numbered placeholders.
String personName = 'Ada'; Integer visits = 3; String message = 'Welcome back ' + personName + ', visit number ' + visits + '.';
Every + is a place where a space can go missing, and the shape of the finished sentence is buried in the quotes.
String.format() takes a template and a List<String> of values. The placeholders {0}, {1}, and {2} are replaced by the matching item in the list:
String message = String.format(
'Welcome back {0}, visit number {1}.',
new List<String>{ 'Ada', '3' }
);
System.debug(message); // Welcome back Ada, visit number 3.
The sentence now reads as a sentence, and the values sit together in one list.
The second argument is a List<String>, so anything that is not text has to be converted first. String.valueOf() turns any value into its text form:
Integer visits = 3;
List<String> values = new List<String>{ 'Ada', String.valueOf(visits) };
The same placeholder number can appear more than once, which concatenation cannot do without repeating the variable:
System.debug(String.format('{0} and {0} again', new List<String>{ 'echo' }));
// echo and echo again
Placeholders count from zero, so the first value is {0} and not {1}. A placeholder with no matching item in the list is left in the text exactly as it was written.
Messages shown to users, error text, and log lines all read better when the wording is written in one piece. String.format keeps the sentence in one place and the values in another, which makes both of them easy to change later.