Bom, quando você chama o valueOf de um objeto, internamente é chamado o método toString desse objeto. No caso de uma String, o valueOf retorna a própria String.
Se você tivesse chamado o valuOf para um objeto qualquer, ao invés de o valor da referência, você iria ver um número estranho precedido do caracter "NomeDaclasse@". Esse número é o hashCode do objeto. Ou então, se esse objeto tiver sobrescrito o método toString, você verá a String que representa esse objeto. Por exemplo:
public class Cachorro {
}
Cachorro cachorro = new Cachorro();
String s = String.valueOf(cachorro);
System.out.println(s);
A saída é:
Cachorro@addbf1
Agora se você tivesse sobrescrito o método toString da classe Cachorro, teríamos:
public class Cachorro {
public String toString() {
return "au! au!";
}
}
Cachorro cachorro = new Cachorro();
String s = String.valueOf(cachorro);
System.out.println(s);
A saída seria:
au! au!
Ou seja, valueOf sempre retornará uma String e no caso de objetos, ele chama o método toString() do referido objeto.