Uma forma talvez não canonica de entender construtures é assim
o que significa a linha:
int i;
vc declara uma variavel (i) como sendo do tipo primitivo inteiro (int), certo?
qual o valor de i, quando vc for usar ? não está definido! Vc tem que dizer que seu i vale X antes de usa-lo, sob pena do seu programa não compilar.
agora… e se for algo assim
Object o;
vc também tem uma variavel, no caso ela não é primitiva, ela é um java.lang.Object. qual o ‘valor’ dela?
também não está definida. entretanto um objeto possui ‘valor’? um objeto possui atributos e métodos, logo não é algo que se possa chamar simplesmente de ‘valor’.
quando vc faz isso
int i;
i = 1034;
vc passa um valor primitivo, literal, para uma variavel.
vc não pode fazer isso
Object o;
o = 4593;
não faz sentido! faria sentido se vc tivesse um atributo publico do tipo inteiro
o.meuInteiro = 4795;
ou um método que entendesse isso
o.setAlgumaCoisa(3459);
porem, o seu objeto possui estes caras? AINDA NÃO! quando vc declara, vc ‘marca’ a sua variavel. vc precisa criar um novo objeto e carregar os atributos e/ou métodos necessários para a sua correta utilização.
Object o = new Object();
agora sim faz sentido algumas coisas como
if(o.equals(outroObjeto)){ … }
ai vc vai dizer ‘puxa mas pq eu tenho q fazer isso…’
por 2 motivos
- seu objeto pode receber um valor ‘nulo’
o = null
nesse caso seu objeto está ‘vazio’ e não tem nenhum método ou atributo, se vc tentar usar vai acabar acontecendo um NullPointerException. Quando isso acontece? imagine que vc fez uma consulta, vc quer um objeto que tenha todos as linhas de um banco de dados. se não for encontrado nada, o objeto PODE vir nulo. se o objeto PODE ser nulo, vc tem que analisar depois se o resultado é nulo ou não.
- vc pode usar outros construtores que não o do tipo do seu objeto
ClasseA algo = new ClasseB();
InterfaceA algo = new ClasseB();
eis algo não incomum em java, que possui as suas utilidades 