Olá Hugo!
Ele não poderia ser instanciado no try pois você estaria tornando ele uma variável do tipo local, dessa forma o finally não teria acesso aos métodos de conexão e não iria conseguir fechar.
É necessário criar a variável do lado de fora para que o finally consiga acessar.
Vou tentar explicar o fluxo que pode acontecer em cada um dos casos:
INSTANCIA FORA DO TRY
1 - Ao fazermos "Conexao con = null;" estamos alocando um espaço na memória, por estar fora de escopo, esse local pode ser visualizado por quem está dentro do try e dentro do finally
2 - Quando entramos dentro do try nós pegamos esse espaço que estava na memória e colocamos algo dentro dele (criamos um instância do objeto do tipo Conexao). Isso quer dizer que aquela referencia agora contem atributos e métodos que podem ser acessados.
3 - Ao chegar no finally, como temos um objeto construido podemos chamar o método fecha().
INSTANCIA DENTRO DO TRY
1 - Ao fazermos "Conexao con = new Conexao();" dentro do try estamos criando uma variável de escopo local. Isso quer dizer que a variável só irá existir dentro daquele bloco.
2 - Se tentarmos chamar con.fecha() dentro finally iremos encontrar dois tipos de problemas que impossibilitam essa operação de ocorrer:
Não existe uma referencia global da variável con do tipo Conexao, portanto não é possível realizar esse acesso dentro do finally.
Mesmo que fosse possível acessar, se você não construir o objeto dentro do try você não conseguiria chamar o método dele (pois é somente um espaço vazio na memória).
Para entender esse segundo tópico veja esse exemplo:
Conexao con = null;
try {
con.leDados(); // Aqui vai dar erro
} catch(IllegalStateException ex) {
System.out.println("Deu erro na conexao");
} finally {
con.fecha(); // Aqui vai dar erro
}
Espero que tenha ajudado!
Bons estudos.