Enviar um café pro programador

Pode me ajudar a transformar cafeína em código?

Auto-referência com o this - Invocando métodos de Classes e Objetos

No tutorial de Java passado relacionado a Orientação a Objetos, falamos como criar construtores, com ou sem parâmetros, em nossas classes.

Nesta pequena aula, iremos aprender como referenciar membros de um objeto através da keyword 'this', que é uma ferramenta bastante usada por programadores Java em métodos dentro de Classes.

Referenciando membros da classe com this

Imagine que criemos uma classe chamada "Funcionario", onde seu construtor padrão recebe uma String com o nome do funcionário, um inteiro com seu número de identificação e um double com seu salário.
Se esses dados, dentro da classe são:

private String nome;
private int ID;
private double salario;

E o cabeçalho do construtor é:
public Funcionario( String nome, int ID, double salario)

Como faríamos a atribuição? Ora, do mesmo jeito que fizemos antes:
nome = nome;
ID = ID;
salario = salario;

Epa! Notou que as variáveis da classe e as variáveis do cabeçalho tem o mesmo nome?
E agora, como o Java vai saber que as variáveis da esquerda se referem as variáveis 'private' da classe a as da direita são as que o usuário mandou pra criar o objeto?

Já sei! Basta criar o método com nomes de variáveis diferentes, como fizemos antes:
public Funcionario( String Nome, int id, double Salario){
nome = Nome;
ID = id;
salario = Salario;
}

Ok, isso funcionaria perfeitamente. Mas seria extremamente incômodo, e desorganizado, criar dois nomes pra um mesmo tipo de variável.
Não pode parecer problema agora, com essa simples aplicação. Mas em uma situação real, em que seu programa em Java terá centenas de variáveis e você tiver que criar e decorar nomes de variáveis, isso vai ser um baita problema.

Para isso, existe o 'this', que referencia - ou seja, aponta - a própria classe!
'this' em inglês, significa 'isso', 'isto'. É bem fácil seu uso, veja como ficaria nosso construtor:

public Funcionario( String nome, int ID, double salario){
this.nome = nome;
this.ID = ID;
this.salario = salario;
}

Pronto.
Agora ficou óbvio que 'this.nome' é a variável 'nome' da classe "Funcionario" e 'nome' é a variável que a classe recebeu para criar um objeto!

Usamos o 'this' dentro da classe. Assim, sempre que colocarmos 'this.' antes de uma variável, fica implícito ao Java que estamos nos referindo aos atributos daquela Classe.
Podemos usar, inclusive, em um print, caso esteja dentro da classe. Em um método, por exemplo, como veremos a seguir.

Outra utilidade do 'this' é passar o objeto atual como parâmetro.
public Object getObjeto(){
     return this;
}

Outro exemplo disso é criar o método...:
public String toString()

...na sua classe, e usar 'this' dentro de um print. O Java entenderá que deve ser impresso o que estiver dentro desse método 'toString()'.

Outra utilidade do 'this' é invocar outros construtores. Para invocar um construtor dentro de outro, essa chamada deve ser o primeiro comando do construtor atual.
Por exemplo, fazendo simplesmente:
this;

Estamos chamando o construtor padrão, que não recebe parâmetros.
Fazendo:
this(2112);

Estamos invocando o construtor que recebe um inteiro como parâmetro.
Lembrando que quando criamos um construtor que não é o padrão, o Java não vai mais criar o construtor padrão vazio.
Esse construtor padrão vazio só é criado automaticamente quando não criamos nenhum construtor.


Como invocar métodos de objetos que criamos


Vamos criar um método, dentro da classe "Funcionário", que exibe todas as informações de um objeto dessa classe. Vamos chamar de 'exibir':

public void exibir(){
System.out.printf("O funcionário %s, de número %d recebe %.2f por mês", this.nome,this.ID,this.salario);
}


Para invocar, basta colocar '.exibir()' após o nome do objeto, que fará com que este método rode.
Note, porém, que conforme explicamos em nosso artigo sobre Classes e Objetos, essa classe é apenas uma abstração.
Ou seja, esse método não existe de verdade! Ele só vai passar a existir quando criarmos um objeto dessa classe!
(Na verdade ele pode existir, caso a classe fosse estática. Estudaremos isso em breve).

Para ilustrar a chamada de métodos de um objeto e o uso do 'this', vamos criar um funcionário - um objeto - de nome 'chefe'.
O código ficará assim:

thisMetodo.java

public class thisMetodo{
    
    public static void main(String[] args){
        String nome = "Neil Peart";
        int ID=2112; 
        double salario = 1000000;
        
        Funcionario chefe = new Funcionario(nome, ID, salario);
        
        chefe.exibir();
    }

}


Funcionario.java

public class Funcionario {
    private String nome;
    private int ID;
    private double salario;
    
    public Funcionario(){
        System.out.println("Método construtor padrão invocado!");
    }

    public Funcionario( String nome, int ID, double salario){
        this();
        System.out.println(this);

        this.nome = nome;
        this.ID = ID;
        this.salario = salario;
    }

    
    public String toString(){
        return "Foi usado : System.out.println(this)";
    }

    public void exibir(){
        System.out.printf("O funcionário %s, de número %d recebe %.2f por mês", this.nome,this.ID,this.salario);

}

24 comentários:

Anônimo disse...

Tudo bem é que este assunto é
complicado e ficou um
pouco confuso. apesar de muito bem explicado, me fale quando
uso o THIS estou me referenciando as
variáveis da linha ((parâmetros))

ex: public Funcionario( String nome, int ID, double salario){....}
ou as que ficam dentro da classe.

private String nome;

private int ID;

private double salario;



desculpe se ofendi.

Tutorial Java Progressivo disse...

Olá Anônimo, agora que foi mais específico, vamos tirar sua dúvida.

Olha esses trechos tirado do próprio artigo:
"Para isso, existe o 'this', que referencia - ou seja, aponta - a própria classe!"

Esse também:
Agora ficou óbvio que 'this.nome' é a variável 'nome' da classe "Funcionario" e 'nome' é a variável que a classe recebeu para criar um objeto! "

Ou seja, o this.ALGO se refere ao elemento 'ALGO' da classe, e não dos parâmetros.
O elemento do parâmetro é o que tem somente 'ALGO'.

this.ALGO = ALGO;
(da classe) (do parâmetro)

Anônimo disse...

não consegui entender essa parte...

public Funcionario( String nome, int ID, double salario){
this();
System.out.println(this);

o que faz esse primeiro "this"

será q da pra explicar melhor

Java disse...

Anônimo,

Ele chama o construtor padrão.
Você leu essa parte do tutorial em diante?

"Outra utilidade do 'this' é invocar outros construtores. Para invocar um construtor dentro de outro, essa chamada deve ser o primeiro comando do construtor atual.
Por exemplo, fazendo simplesmente:
this;
..."

Qualquer dúvida, poste novamente.

Anônimo disse...

acho que entendi só q o meu código tava apontando um erro naquele this();

consegui arrumas colocando um construtor padrão sem parâmetros, pq no código postado só tem construtor com parâmetros...

Java disse...

Tem razão, faltou o padrão.

Vamos adicionar algo assim:

public Funcionario(){

System.out.println("Construtor padrão invocado pelo comando 'this()');

}

Obrigado pela contribuição.

Anônimo disse...

Então cara, quer dizer que i this()
chama o construtor em qualquer local da classe?

Apostila Java Progressivo disse...

Chama o construtor default.

Lembrando que, caso não tenha criado nenhum construtor, o Java cria um (que não faz nada).

Caso você crie um construtor, mesmo que não seja o default, o Java não criará nenhum.

Então, se você cria um construtor que recebe um parâmetro, ele será o único existente. Aí chamar só this() dará um erro no Java.
Teria que ser this(parâmetro);

João Victor disse...

Boa noite !!

primeiro, gostaria de agradecer pelo material.
Está sendo muito útil para mim ..

Mas vocês podem me tirar uma dúvida..

O que essa linha faz exatamente..

public String toString(){
return "Foi usado : System.out.println(this)";
}


Obrigado !

Apostila de Java disse...

Olá João Victor,

Quando imprimimos:
System.out.println(this);

Ele sempre vai imprimir o retorno da função toString(), e a gente pode escolher o que colocar nessa função.

Anônimo disse...

Olá! Seu curso e muito bom mesmo..

Eu tó tendo um problema nesse trecho de codigo

public Funcionario( String nome, int ID, double salario){
this();
System.out.println(this);

this.nome = nome;
this.ID = ID;
this.salario = salario;
}

precisamente no "this();"
constructor funcionario in class funcionario cannot be appied to given types;
required: String, int, double
found: no arguments
reason: actual and formal argument lists differ in lenght

Apostila Java Progressivo disse...

Bem notado, anônimo.

O this() é pra invocar o construtor padrão, que havíamos esquecido de criar.

Criamos um que simplesmente exibe uma mensagem. Assim, quando usar this(), essa mensagem será exibida.

Margeo disse...

Excelente curso, estava me preparando para certificação java pelo livro da Katy Sierra, e em muitos pontos dava uma travada, com o seu material está facilitando minha vida. Obrigado!

Unknown disse...

Parabéns pelo curso, estou conseguindo evoluir e muito com o mesmo. Nesse exemplo fiquei com a seguinte dúvida:
O método "public String toString()é utilizado apenas para imprimir a mensagem. Pude ver que quem "chama" esse método é a linha System.out.println(this); que está dentro do construtor.
É aí que não entendi, como esse (this) faz essa chamada?

Seguindo as aulas aprendi que para se chamar o método, basta "chamar".

Porque e como, ao utilizar o System.out.println(this), ele chama o método String??????

Desde já obrigado e, mais uma vez parabéns por todo o trabalho e curso prestado.

Apostila Java Progressivo disse...

Ótima pergunta, Wanderley.

O método toString() é um método especial, que existe em todos os Objetos!

Ele é especial porque podemos 'imprimir' um objeto.
Por exemplo, vamos criar uma classe chamada "Carro" e criar o objeto "fusca".

Se colocarmos o objeto "fusca" dentro de um print, ele vai imprimir automaticamente o que estiver no método toString(), pois esse método sempre retorna uma String.

Poderíamos usar o método toString() para exibir o modelo do carro, ano e preço dele.
Aí fazíamos:
System.out.println(fusca);
System.out.println(hilux);
etc

Onde "fusca" e "hilux" são objetos, e automaticamente o toString() ia retornar a String que implementamos lá.

E se fizermos:
System.out.println(this);

Estamos imprimindo o objeto atual, ou seja, isso automaticamente invoca o que estiver na toString() daquele objeto, pois o 'this' aponta para o próprio objeto.

Unknown disse...

Agora deu para entender melhor o funcionamento do toString(), muito obrigado, esta me ajudando muito!

Alex disse...

1º queria agradecer pelo curso que é excelente!!!....
só fiquei com uma dúvida.... as classes:
public class thisMetodo e public class Funcionario temos de fazer separadamente?? eu uso notepad++ para fazer o codigo e e faço compilação com CMD

Binho disse...

Amigos bom dia,

Nesse método suponha que preciso de um Scanner, como eu utilizo? invoco na classe exibir ou na main?

obrigado.

José disse...

Já vi que autor é fã da de Rush.

Rian disse...

Nunca entendi o uso do this até ler isso, ele generaliza as coisas.

Mas não consegui chamar os construtores por meio do this(); ou this(args);

entendi que pra ele chamar o construtor de uma classe this() precisa estar dentro da propria classe. Mas qualquer função que eu utilize o this() me da o seguinte erro "call to this must be first statement in constructor". De todos os teste que tentei não consegui fugir desse erro. tentei fazer uma função static q invocasse o construtor, tentei invocar construtor com parametro dentro do sem parametro....


tem como fazer um exemplo que possa ser utilizado o this pra invocar construtores? percebi tb nos comentários que isso é uma dúvida frequente.

Obrigado.

T.S.A disse...

This é usado para fazer auto-referência ao próprio contexto em que se encontra. Resumidamente, this sempre será a própria classe ou o objeto já instanciado.
public class TV {
//atributos
int tamanho;
int canal;
boolean ligada;

// método contrutor com parâmetro
TV(boolean ligada) {
this.ligada = ligada;
/*
* Onde this.ligada é o atributo
* e ligada é o valor do parâmetro
*/
}
}

Anônimo disse...

Hi, podem me chamar de SSCat

como vocês podem vê no exemplo, tem uma referencia muito legal, o salário é o que todos querem...
brinks
O nome dado é Neil Peart, caso vocês pesquisem, verão isso aqui:
Neil Ellwood Peart, OC, é um músico canadense, baterista da banda de rock progressivo Rush, e escritor.

Realmente ele curte Rush kkkk

jose luciano disse...

bom dia, nao consigo acessar as video aulas, tem algum outro endereco para elas?

mauroslucios disse...

Aulas da Universidade XTI
https://www.youtube.com/playlist?list=PLxQNfKs8YwvGhXHbHtxtoB-tRRv6r3Rlr

Contribuir com o Java Progressivo

Que tal apoiar e fazer crescer o ensino da programação no Brasil ?

Ajudar nosso país a crescer e se desenvolver cada vez mais, tecnologicamente?

Clica abaixo pra saber mais!

Apoiar o Projeto Progressivo


Tutoriais de Java