Final (Constantes)

Olá pessoal sou novo no fórum e também sou novo no mundo das tecnologias JAVA. Além de suprir minhas dúvidas espero poder ajudar.

Como primeira dúvida gostaria que me ajudassem com o tipo constante Final.

Compreendo bem a teoria desta constante, se criar uma constante Final o valor desta não poderá ser alterada.

Minha dúvida é a seguinte, tenho duas classes uma principal e uma secundária contendo funções. Toda a vez que utilizo alguma função da classe secundária passo algumas variáveis, para que estas possam ser alteradas pela função, até ai tudo bem, porem se a função secundária contiver uma chamada de outra função dentro dela o java obriga que os parâmetros sejam do tipo Final. Bom ninguém deve estar entendendo nada, não estou conseguindo explicar direito porem vou colocar a baixo um exemplo e vocês vão entender.


public class Principal
{

   public Secundaria secundaria;
   public JButton button;
   public Variavel variavel

   public Principal()
   {
      secundaria = new Secundaria();
      button = new JButton();
   }

   secundaria.alteraButton(button, variavel);

}

public class Secundaria
{

   public alteraButotn(JButton button, Variavel variavel)
   {
      button.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            //aqui eu atero alguma propriedade da variavel
         }
      });
   }
}

O código acima é só um exemplo do meu problema, e não é um código compilável. Bom o que acontece é que não consigo alterar o valor da variável porque o java insiste que o parâmetro “Variavel variavel” seja “Final Variavel variavel”, alguém tem alguma solução alguma tática para que isso não ocorra, como disse sou novo no java e não sei quase nada.

A parte dos parâmetros da função secundária obrigatoriamente ficaria:

[“Final Variavel variavel”]

Com isso não consigo alterar o valor da variavel.

public class Secundaria
{

   public alteraButotn(JButton button, Final Variavel variavel)
   {
      button.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            //aqui eu atero alguma propriedade da variavel
         }
      });
   }
}

Se quiserem que poste o meu código para verem o real erro eu posto, porem é quase a mesma situação.

Agradeço desde já.
Abrigado.

Na verdade acho que a idéia é não poder mudar msm… o que vc pode fazer é criar um método na sua classe Secundaria e chamar esse metodo dentro do actionPerformed… ai vc poderá alterar o valor desse atributo…

ok?

Eh o seguinte caro amigo, este codigo:

 button.addActionListener(new ActionListener(){  
          public void actionPerformed(ActionEvent e){  
             //aqui eu atero alguma propriedade da variavel  
          }  
       });  

utiliza o que chamamos classe interna anonima local de argumento (new ActionListener(){…). Objetos residem no heap, variaveis locais de metodo residem na pilha. Como ha um objeto tratador de eventos (new ActionListener()), apos o termino da execucao do metodo, as variavaveis locais serao destruidas, e este objeto poderia ser passado adiante e - e ainda estar ativo no heap - e tentar acessar algumas dessas variaveis que nao existem mais!!! Por isso as va
riaveis locais de um metodo de uma classe interna anonima local de argumento deve ser marcada como final.

Entendi, era mais ou menos isso que eu desconfiava ser, você teria alguma alternativa para o ocorrido?

Muito obrigado as duas respostas.

Não compreendi bem a do renamed, se puder dar um exemplo!!!

Tenta passar o this, dai vc pode alterar as variaves do objeto.

Ja tentei passar o this, não deu certo, continua obrigando a passar a variavel como Finail.
Alguém tem alguma outra idéia?

Realmente vc só pode ter acesso a variáveis finais dentro de uma class anónima que é o que vc está criando ali no new ActionListener
Vc não pode mudar a variável. è impossivel. Mas pode utilizar um objeto que acesse a variável , assim:


public class Principal
{

   public Secundaria secundaria;
   public JButton button;
   public Variavel variavel

   public Principal()
   {
      secundaria = new Secundaria();
      button = new JButton();
   }

   secundaria.alteraButton(button, this);

}

public class Secundaria
{

   public alteraButotn(JButton button, final Principal principal)
   {
      button.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
            //aqui eu atero alguma propriedade da variavel
              principal.variável = // novo valor
         }
      });
   }
}

Lembre-se. Java é oerientado a objetos, não a variáveis.

Olá,

Eu não entendo porque isso é um problema… repare no seguinte detalhe:

[code]meuMetodo(final Variavel variavel) {
// A linha abaixo é válida, eu posso modificar um atributo do objeto normalmente
variavel.atributo = “oeeeee”;

// O que não pode é fazer uma nova atribuição para a variavel, como aqui:
variavel = new Variavel(); // Essa linha não compila.
}[/code]

Se for o primeiro caso, tudo Ok, não existe nenhum erro.

Se o que estiver tentando é a segunda opção, então das duas uma:
1) Você precisa de uma nova variável para trabalhar localmente dentro do método: Não há necessidade de alterar o parâmetro, crie uma nova variável do mesmo tipo e faça o que precisar com ela.

meuMetodo(final Variavel variavel) { Variavel varAuxiliar = ..... ; // Faz o que precisar... }
2) Talvez imagine que alterando a variável dentro do método o atributo da classe Principal seja alterado junto. Isso não está correto, pois em Java os parâmetros são passados por valor. Se tiver dúvidas sobre isso pode postar que o pessoal explica em mais detalhes, mas a conclusão é que não é no Final que está o problema, ele não tem nada a ver com isso.

Se precisa alterar a propriedade do objeto Principal, veja as dicas anteriores.

Olá pessoal estão me ajudando muito. Obrigado.

Só para completar estava lendo em alguns lugares e fiz alguns testes, a variavel na verdade ela muda e não muda, o que descobri é que dentro do metodo ela muda, quando o metodo acaba ela restorna ao valor inicial, achei meio estranho e não compreendi direito algo que acontece.

Fiz os testes colocando um print na tela.


public class  Principal  
{  
   
    public Secundaria secundaria;  
    public JButton button;  
    public Variavel variavel  
   
    public Principal()  
    {  
       secundaria = new Secundaria();  
       button = new JButton();  
    }  
   
    secundaria.alteraButton(button, variavel);  
   
 }  
   
 public class Secundaria  
 {  
   
    public alteraButotn(JButton button, Variavel variavel)  
    {  
       button.addActionListener(new ActionListener(){  
          public void actionPerformed(ActionEvent e){
             variavel = 12;
             System.out.print(variavel); 
             //variavel aparece com o valor 12 
          }  
       });
       System.out.print(variavel);
       //aqui a variavel tem o valor da funcao principal  
    }  
}  

Alguém poderia me explicar melhor este caso?

Em realação ao meu problema consegui resolver colocando tudo dentro da classe principal. O meu problema era que tinha um classe principal com várias variaveis, criei outra classe para criaçao de um JMenuBar, neste JMenuBar teria um item chamdo opem que abriria um arquivo de texto e carregaria as variaveis da classe principal, por isso teria que passa-las para classe JMenuBar e altera-las la dentro e mais a alteraçao teria que acontecer dentro de um actionPerformaced.

segue o código parcial. Acho que agora fica melhor para entender o meu problema, bom agradeço desde já coloquei tudo na classe principal e deu certo, porem gostaria de dividir em duas classes como o código abaixo para ficar um código melhor. A variavel “net” muda dentro do metodo actionPerformaced quando sai deste metodo ela voltar a ser tudo 0.

public class WWJ extends JFrame
{
	public int net;
	public MenuBar menubar;	

	public WWJ()
	{
		net = new int[100][100];
		menubar = new MenuBar();
		this.add(menuBar.createMenuBar(net)
	}
}

public class MenuBar
{

	public MenuBar()
	{

	}

	public void creatMenuBar(net)
	{
        	JMenu menuFile = new JMenu("File");
	        JMenu menuOpen = new JMenu("Open");
                menuFile.add(menuOpen);

	        itemOpenNet.addActionListener(new ActionListener(){
                    public void actionPerformed(ActionEvent e){

        		JFileChooser eleitor = new JFileChooser();
        		eleitor.setCurrentDirectory(new File("."));
        		int result = eleitor.showOpenDialog(null);

        		if(result == JFileChooser.APPROVE_OPTION)
       			{
            			File arquivo = eleitor.getSelectedFile();
            			String caminho = arquivo.getPath();
            
            			String nomeItem = e.getActionCommand();
            			if(nomeItem.equals("Open Net"))
            			{
                			net = function.readNet(caminho);
            			}
                    	}
                });

        	JMenuBar menuBar = new JMenuBar();
        	menuBar.add(menuFile);
		
	}

}