Static [RESOLVIDO]

Eae pessoal,

Bom, estava dando uma estudada sobre o que é e para que serve a palavra-chave static e entendi que ela é usada para que variáveis e métodos tenham apenas uma referência na memória, e consequentemente para que não sejam “zeradas” toda vez que uma instancia é criada. E que métodos static só acessam métodos e atributos static, a não ser que uma instancia seja criada e etc.

O ponto que eu não entendi muito bem é a parte do this, nos materais que eu li, inclusive no artigo que todo mundo indica aqui no guj, eles falam que membros que possuem a palavra static não tem acesso ao ponteiro this. E até ai tudo bem, mas eu não consegui entender bem o porquê.

No material da caelum a parte que explica sobre o static e sua relação com o ponteiro this é essa:" Métodos e atributos estáticos só podem acessar outros métodos e atributos estáticos da mesma classe, o que faz todo sentido já que dentro de um método estático não temos acesso à referencia this, pois um método estático é chamado através da classe, e não de um objeto. "

" método estático é chamado através da classe, e não de um objeto ", como assim? pelo o que eu li no livro dos deitel classe é só uma “planta”, as classes não “chamam” ninguem, quem executa as tarefas da classe são os objetos dela. Então como é possivel um método estático ser chamado através da classe e não de um objeto?.

Se alguém conseguir me explicar ou me corrigir em um ponto em que eu esteja me equivocando eu agradeceria muito.

Bem, teoricamente, se tens uma classe:

[code]public class A {

private static int count;

public A(){
count++;
}

public static int getNumCriacoes(){
return count;
}
}[/code]

O atributo count não está associado a uma instancia do Objeto A, ou seja,

new A().count == new A().count

Quando ele fala:
" método estático é chamado através da classe, e não de um objeto "
ele quer dizer que para chamar um método estático, você precisa da classe do método, por exemplo:

System.out.println(A.getNumCriacoes());

No Java, podemos fazer também new A().getNumCriacoes(), mas vai te dar um warning, porque na verdade, quando estas acessando um método/atributo estático, você não está acessando uma ‘variável/método’ do objeto criado, e sim da classe existente, nesse caso A.

OK, não sei se ajudei ou piorei…

O operador this serve para autoreferencia. Para o objeto em questão acessar seus atributos ou métodos de instância (não estáticos).

Métodos e atributos declarados como estáticos só podem ser acessados no contexto estático.

A idéia é que você não precisar criar um objeto para acessar membros estáticos, dessa forma, deve ser usado o nome da classe para acessar o escopo estático.

Resumindo:
Sao dois escopos: de classe (static) e de objeto ou instancia (dai voce pode usar o operador this).

Só um parênteses. O this serve também para casos de ambiguidade. Para acessar explicitamente membros do objeto, como abaixo:

class Teste
{
   String nome;
   public void setNome(String nome) { this.nome = nome; }
}

Se não usarmos o this o valor recebido por parametro nao vai ser atribuido corretamente para o atributo. :smiley:

Boa dia meu caro amigo m-bax todos os aspectos citados sobre a palavra chave static estão completamente certos, referente a essa sua ultima pergunta citada acima, funciona da seguinte forma, por exemplo se você não define um construtor para uma classe, ela por default já possui um construtor implicito vazio certo?
Quando usamos a classe String por exemplo, nós usamos da seguinte forma String variavel = “valor”, você pode perceber que String é um objeto? mais sendo um objeto não teriamos que instancia-lo?, para ficar assim String variavel = new String(), variavel = “valor”.
Pois bem ae que vem a resposta, quando você define um atributo ou metodo sendo do tipo static você esta dizendo pro JAVA instancia-lo implicitamente, ou seja você não precisa instancia-lo, mais o JAVA por baixo dos panos já faiz isso por você, da mesma forma com que ele faiz para Strings e também para construtores!

[quote]O ponto que eu não entendi muito bem é a parte do this, nos materais que eu li, inclusive no artigo que todo mundo indica aqui no guj, eles falam que membros que possuem a palavra static não tem acesso ao ponteiro this. E até ai tudo bem, mas eu não consegui entender bem o porquê.

No material da caelum a parte que explica sobre o static e sua relação com o ponteiro this é essa:" Métodos e atributos estáticos só podem acessar outros métodos e atributos estáticos da mesma classe, o que faz todo sentido já que dentro de um método estático não temos acesso à referencia this, pois um método estático é chamado através da classe, e não de um objeto. " [/quote]

referente ao this o mesmo é usado para fazer referencia ao atributo daquela classe, por exemplo:

[code]public abstract class Pessoa {

private String nome;

public String getNome() {
	return nome;
}
public void setNome(String nome) {
	this.nome = nome;
}

}[/code]

No metodo setNome(String nome) fica claro que o mesmo recebe por parametro uma String chamada “nome” que também tem o mesmo nome do atributo da classe Pessoa chamado “nome”
então o this.nome faiz referencia ao atributo da classe, isso quer dizer que this.nome = nome; ou seja este nome “atributo da classe pessoa recebe da variavel nome passada por parametro um valor”, se não fosse utilizado o this, ficaria impossivel definir qual variavel nome é referente a classe e qual variavel nome foi passada por parametro.

Referente a metodos static, se o metodo é static isso significa dizer que qualquer variavel que estiver definida dentro desse metodo ira receber um valor vindo de fora, com isso é desnecessario o uso do “this”, usa-lo seria a mesma coisa de falar que a agua é molhada!, hehe sendo que todos nós sabemos que a agua é molhada, ou seja tambem sabemos que quando usamos um metodo static o atributo será estatico ou seja tera um unico valor pra todos que o usarem e esse valor vira de fora!

espero ter ajudado!

Então pessoal,
Muito obrigado a todos que responderam, mas eu esqueci de postar que encontrei um trecho aqui no livro dos Deitel que explica exatamente o que eu estava em dúvida. Então para complementar o que foi dito, e para que outras pessoas que ainda não entenderam bem essa relação do this e métodos static ai vai:
" Um método static não pode acessar membros de classe não static, porque um método static pode ser chamado mesmo quando nenhum objeto da classe foi instanciado. Pela mesma razão, a referência this não pode ser utilizada em um método static. A referência this deve referenciar um objeto específico da classe, e quando um método static for chamado, poderia não haver nenhum objeto de sua classe na memória. "

Caro Dostoiévski,

Se sanou sua dúvida, adicione [Resolvido] no título do tópico.

[quote=RafaelCassau]Quando usamos a classe String por exemplo, nós usamos da seguinte forma String variavel = “valor”, você pode perceber que String é um objeto? mais sendo um objeto não teriamos que instancia-lo?, para ficar assim String variavel = new String(), variavel = “valor”.
Pois bem ae que vem a resposta, quando você define um atributo ou metodo sendo do tipo static você esta dizendo pro JAVA instancia-lo implicitamente, ou seja você não precisa instancia-lo, mais o JAVA por baixo dos panos já faiz isso por você, da mesma forma com que ele faiz para Strings e também para construtores!
[/quote]
Não diria que é exatamente implícito. Há uma regra para isso, ou seja, você pode definir esse momento.

Vamos considerar a seguinte classe:

public class StaticTest { static String test = "testme"; //Você teve que declarar "explicitamente" a instância a ser atribuida à variável estática. Falta apenas ver quando a mesma ocorre. }
Mas só fazer isso não fará com que a variável esteja disponível. É necessário que a classe tenha sido carregada pelo ClassLoader.
Um primeiro teste que podemos fazer:

public class Test { public static void main() { //Isto não torna a variável estática disponível: Class staticTest = StaticTest.class; } }
Isso só disponibilizou o contrato, mas o mesmo não foi alocado no classLoader.
Porém, fazendo as seguintes alterações:
Na classe StaticTest adiciono um bloco estático que executa um sysout.

class StaticTest { static String test = "testme"; static { //Bloco estático. Será invocado logo após instanciar as variáveis estáticas System.out.println(test); } }
Caso mantenha a classe main (Test) inalterada. Ainda assim o bloco estático não será executado. Então precisamos fazer outra alteração na classe main:

public class Test { public static void main(String[] args) { try { Class staticTest = Class.forName("StaticTest"); //Essa chamada põe a classe StaticTest no ClassLoader. } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
Verá na console que o sysout ocorreu.
Porém, neste caso, eu não invoquei a classe explicitamente (mas corro o risco de uma ClassNotFoundException).
Vamos fazer uma última alteração no main:

public class Test { public static void main(String[] args) { String tested = StaticTest.test; System.out.println("Testado = " + tested); } }
Veja que aqui também ocorreu o bloco estático.