PrintStream - Diferença de método e objeto?

Tenho dois exemplos de parte de código abaixo:

1: O código abaixo funciona perfeitamente:

PrintStream escreva = System.out;
escreva.print( );

2: Já o código abaixo não funciona:

PrintStream escreva = System.out.print;
escreva( );

Pergunta?

Por que o exemplo 2 não funciona?

1 curtida

Porque print é um método, e não tem como atribuir um método de um objeto a uma variável em Java. Não por enquanto, mas acredito que a tendência do Java é absorver cada vez mais o paradigma funcional.

O mais perto disso que você pode chegar é utilizando lambdas no Java 8:

Runnable x = () -> {
    instrucao1;
    instrucao2;
    ...
};

Isso não é atribuir um método a uma variável, é uma forma sucinta de escrever interfaces funcionais anônimas.

Ou então, utilizando referências à métodos (Java 8 também):

List<String> listaDeStrings = Arrays.asList("oi", "tchau", "hello", "world");
listaDeStrings.forEach(System.out::println);
2 curtidas

Vamos por partes. Você sabe a diferença entre um objeto e um atributo?
Quando você escreve System.out está acessando um atributo (uma referência de objeto) denominada out e que pertence a classe System (é estático). Note que ele não precisa de parênteses após sua chamada.
Quando você chama System.out.print() ou atribui a instância de objeto out a uma variável do tipo PrintStream, como fez com o objeto escreva e invoca escreva.print() você está informando a maquina virtual java que ela deve exibir algum conteúdo na saída padrão.
O código PrintStream escreva = System.out.print; escreva( ); não vai funcionar por que o método print não retorna um objeto (sua declaração é void) e o mesmo não é um atributo, é um método.

1 curtida